go 问题请教,想问下下面的代码为啥会导致死锁,导致的死锁如何解决

2020-12-15 15:30:21 +08:00
 zhengdai1990

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 }

912 次点击
所在节点    问与答
11 条回复
barbery
2020-12-15 15:40:44 +08:00
本来想尝试解答一下,点进来看到代码。。。
caryqy
2020-12-15 15:42:41 +08:00
https://play.golang.org/ 代码在这里粘贴然后分享出来
whitehack
2020-12-15 15:44:33 +08:00
本来想尝试解答一下,点进来看到代码。。。
rimutuyuan
2020-12-15 15:44:50 +08:00
本想复制到 IDE 里格式化一下,但因为有注释并且没换行。。。。
zhengdai1990
2020-12-15 16:07:41 +08:00
zhengdai1990
2020-12-15 16:08:04 +08:00
@rimutuyuan 贴之前是有换行的……大佬看附言
zhengdai1990
2020-12-15 16:08:15 +08:00
@barbery 大佬看下附言
zhengdai1990
2020-12-15 16:08:42 +08:00
@whitehack 大佬看下附言
zhengdai1990
2020-12-15 16:09:36 +08:00
我的理解是 reply 那个 channel 是同步的,不能光发送不接收
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
zhengdai1990
2020-12-15 22:50:07 +08:00
@Nitroethane 老师出的作业啊,天坑

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/735682

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX