如何在不产生死锁的情况下拥有一个缓冲通道和多个阅读器?
Posted
技术标签:
【中文标题】如何在不产生死锁的情况下拥有一个缓冲通道和多个阅读器?【英文标题】:How can I have one buffered channel and multiple readers without producing a deadlock? 【发布时间】:2016-06-06 17:41:54 【问题描述】:致命错误 所有 goroutine 都处于休眠状态。死锁。
这是我尝试过的。我打电话给wg.Done()
。缺少什么?
package main
import (
"fmt"
"strconv"
"sync"
)
func sender(wg *sync.WaitGroup, cs chan int)
defer wg.Done()
for i := 0; i < 2; i++
fmt.Println(i)
cs <- i
func reciever(wg *sync.WaitGroup, cs chan int)
x, ok := <-cs
for ok
fmt.Println("Retrieved" + strconv.Itoa(x))
x, ok = <-cs
if !ok
wg.Done()
break
func main()
wg := &sync.WaitGroup
cs := make(chan int, 1000)
wg.Add(1)
go sender(wg, cs)
for i := 1; i < 30; i++
wg.Add(1)
go reciever(wg, cs)
wg.Wait()
close(cs)
【问题讨论】:
【参考方案1】:你应该在wg.Wait
之前关闭频道。
您所有的接收器都在等待来自通道的数据。这就是你有死锁的原因。
您可以在sender
函数的defer
语句处关闭频道。
如果第一次尝试从频道接收不成功(因为频道已经关闭),您还需要wg.Done()
http://play.golang.org/p/qdEIEfY-kl
【讨论】:
【参考方案2】:有几件事:
-
发送者完成后,您需要关闭通道。
在接收器中,覆盖通道
不需要在等待组中添加1并在sender中调用Done
请参考http://play.golang.org/p/vz39RY6WA7
【讨论】:
以上是关于如何在不产生死锁的情况下拥有一个缓冲通道和多个阅读器?的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有超时/死锁的情况下在PROMELA进程中发送和接收?