package main
import ("math/rand"; "time")
const R = 100 // number of readers const W = 10 // number of writers
var done chan bool
func db(reads chan chan int, writes chan int) { state := <- writes for { select { case reply := <-reads: reply <- state case state = <-writes: } } } func main() { reads, writes, done := make(chan chan int), make(chan int), make(chan bool) go db(reads, writes) for r := 0; r < R; r++ { // create R readers go func() { reply := make(chan int) for i := 0; i < 20; i++ { reads <- reply // stops in one out of 10 cases if rand.Intn(10) == 0 {select{}} else {<- reply} time.Sleep(time.Millisecond) } }() } for w := 0; w < W; w++ { // create W writers go func() { for i := 0; i < 20; i++ { writes <- rand.Int() % 100 time.Sleep(time.Millisecond) } done <- true }() } for k := 0; k < W; k++ {<- done} // wait for writers to terminate }
1
barbery 2020-12-15 15:40:44 +08:00
本来想尝试解答一下,点进来看到代码。。。
|
2
caryqy 2020-12-15 15:42:41 +08:00
https://play.golang.org/ 代码在这里粘贴然后分享出来
|
3
whitehack 2020-12-15 15:44:33 +08:00
本来想尝试解答一下,点进来看到代码。。。
|
4
rimutuyuan 2020-12-15 15:44:50 +08:00
本想复制到 IDE 里格式化一下,但因为有注释并且没换行。。。。
|
5
zhengdai1990 OP |
6
zhengdai1990 OP @rimutuyuan 贴之前是有换行的……大佬看附言
|
7
zhengdai1990 OP @barbery 大佬看下附言
|
8
zhengdai1990 OP @whitehack 大佬看下附言
|
9
zhengdai1990 OP 我的理解是 reply 那个 channel 是同步的,不能光发送不接收
|
10
Nitroethane 2020-12-15 17:18:19 +08:00
你这写的什么鸡脖玩意儿,看了半天要吐了…… 主要问题出在第 32 行,如果生成的随机数为 0 的话,goroutine 会卡在 这个 if 语句的 select 语句里。而这会引起连锁反应:因为 reply 是无缓冲的,导致第 18 行的代码被卡住,进而第 43 行的代码也被卡住,最后所有 goroutine 全都卡住了。你可以在第 31 行 和 32 行之间加一行 log.Println("random number in reader is 0"),你就会发现,只要这一行打印出来,程序马上 deadlock 。
虽然 channel 可以用来同步 goroutine,但是也不能这样滥用啊。好好学习下这篇文章吧 https://golang.org/ref/mem |
11
zhengdai1990 OP @Nitroethane 老师出的作业啊,天坑
|