弄了一个类似生产者消费者模型,两个协程有一个通道A,不停写入数据,B不停读取数据,因为都是for循环的,是在A里面没有数据的时候关闭Chanel、,还是在B中判断没有数据,超时就退出for循环呢? loop: for{ select { case bb,err := <-addChan: if err == false { break loop } addSlice = append(addSlice,bb) } } 代码类似这样的,但现在出现了协程死锁了,貌似是这里一直在<-addChan读取数据导致的等待超时,死锁了,但有对err判断啊,这里难道不会退出for循环么?谢谢了
if err == false { break loop }
这句貌似永远不会执行。
- 我不知道还有没有其他case语句了,如果没有的话,也就是说只有那一个case的时,当该case无法从
addChan
读取到数据时,整个select
是阻塞的。err
是没有被赋值的。 - 当
B
能读取到值时,err
肯定是true
了。 - 一般是在产生数据的地方关闭channel。
更多评论
- 一般是在生产的地方关闭chanel;
- 在消费的地方判断从Chanel中取出的数据是不是空值或者判断chan是否关闭,如果是空值或关闭跳出循环(PS:如果是允许写入Chanel的数据是空值,或者无法确定写入数据是否有空值的,最牢靠的方式还是判断chan是否关闭)
loop: for { select { case bb, isClosed := <-addChan: if isClosed { break loop } addSlice = append(addSlice, bb) } }
可以看一下同步chan和缓冲chan的相关知识