弄了一个类似生产者消费者模型,两个协程有一个通道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循环么?谢谢了
1. 一般是在生产的地方关闭chanel;
2. 在消费的地方判断从Chanel中取出的数据是不是空值或者判断chan是否关闭,如果是空值或关闭跳出循环(PS:如果是允许写入Chanel的数据是空值,或者无法确定写入数据是否有空值的,最牢靠的方式还是判断chan是否关闭)
```
loop:
for {
select {
case bb, isClosed := <-addChan:
if isClosed {
break loop
}
addSlice = append(addSlice, bb)
}
}
```
可以看一下同步chan和缓冲chan的相关知识
#2
更多评论
`if err == false { break loop }` 这句貌似永远不会执行。
1. 我不知道还有没有其他case语句了,如果没有的话,也就是说只有那一个case的时,当该case无法从`addChan`读取到数据时,整个 `select` 是阻塞的。`err`是没有被赋值的。
2. 当 `B` 能读取到值时,`err` 肯定是 `true` 了。
3. 一般是在产生数据的地方关闭channel。
#1