我正在尝试编写一个程序:package mainimport ( "fmt" "sync")func main() { n := 4 resChan := make(chan []int, n) res := []int{} var wg sync.WaitGroup for i := 0; i < n; i++ { wg.Add(1) go func(i int) { defer wg.Done() resChan <- append(res, i) }(i) } wg.Wait() close(resChan) // code will deadlock without this for subRes := range resChan { res = append(res, subRes...) } fmt.Printf("%v", res)}我认为我有一个缓冲通道,因此对通道的写入不会阻塞。但是,我得到了:fatal error: all goroutines are asleep - deadlock!goroutine 1 [chan receive]:main.main() /tmp/sandbox562058728/prog.go:23 +0x14c有人可以解释为什么代码会这样吗?
2 回答

牛魔王的故事
TA贡献1830条经验 获得超3个赞
如果通道没有关闭,循环将永远不知道何时停止迭代过程。
range-loop 无法从通道中读取,因为它在写入过程中被锁定。另一方面,没有更多数据要通过通道发送。因此,通道在写入过程中被锁定,并且永远不会被解锁。然后它会导致死锁。
Golang Tour页面上有写的注释说:
注意:只有发送方应该关闭通道,接收方不能。在关闭的通道上发送会引起恐慌。
另一个注意事项:频道不像文件;您通常不需要关闭它们。仅当必须告诉接收器没有更多值到来时才需要关闭,例如终止范围循环。
- 2 回答
- 0 关注
- 83 浏览
添加回答
举报
0/150
提交
取消