为了账号安全,请及时绑定邮箱和手机立即绑定

为什么我的代码在没有关闭通道的情况下陷入僵局?

为什么我的代码在没有关闭通道的情况下陷入僵局?

Go
aluckdog 2022-06-27 15:15:32
我正在尝试编写一个程序: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 回答

?
慕桂英546537

TA贡献1848条经验 获得超10个赞

在通道关闭之前,测距通道不会退出 for 循环。



查看完整回答
反对 回复 2022-06-27
?
牛魔王的故事

TA贡献1830条经验 获得超3个赞

如果通道没有关闭,循环将永远不知道何时停止迭代过程。

range-loop 无法从通道中读取,因为它在写入过程中被锁定。另一方面,没有更多数据要通过通道发送。因此,通道在写入过程中被锁定,并且永远不会被解锁。然后它会导致死锁。

Golang Tour页面上有写的注释说:

注意:只有发送方应该关闭通道,接收方不能。在关闭的通道上发送会引起恐慌。

另一个注意事项:频道不像文件;您通常不需要关闭它们。仅当必须告诉接收器没有更多值到来时才需要关闭,例如终止范围循环。


查看完整回答
反对 回复 2022-06-27
  • 2 回答
  • 0 关注
  • 83 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号