我正在使用 Go 构建工作系统的骨架,但我收到了“致命错误:所有 goroutine 都睡着了 - 死锁!”。我使用两个渠道进行协调,一个是创建工作,另一个是发送结果。创建作业后,我关闭了输入通道。我的问题是如何关闭输出通道以便程序可以正确退出。代码是:package mainimport ( "bufio" "flag" "fmt" "log" "math/rand" "os" "time")type Work struct { id int ts time.Duration}const ( NumWorkers = 5000 NumJobs = 100000)func worker(in <-chan *Work, out chan<- *Work) { for w := range in { st := time.Now() time.Sleep(time.Duration(rand.Int63n(int64(200 * time.Millisecond)))) w.ts = time.Since(st) out <- w }}func main() { wait := flag.Bool("w", false, "wait for <enter> before starting") flag.Parse() if *wait { fmt.Printf("I'm <%d>, press <enter> to continue", os.Getpid()) reader := bufio.NewReader(os.Stdin) reader.ReadString('\n') } Run()}func Run() { in, out := make(chan *Work, 100), make(chan *Work, 100) for i := 0; i < NumWorkers; i++ { go worker(in, out) } go createJobs(in) receiveResults(out)}func createJobs(queue chan<- *Work) { for i := 0; i < NumJobs; i++ { work := &Work{i, 0} queue <- work } close(queue)}func receiveResults(completed <-chan *Work) { for w := range completed { log.Printf("job %d completed in %s", w.id, w.ts) }}任何帮助表示赞赏:)
1 回答
米琪卡哇伊
TA贡献1998条经验 获得超6个赞
我错过了关于你知道原始答案中死锁原因的部分。
你提到了WaitGroup,那基本上只是一个信号量
您可以使用另一个“控制”通道,工作人员完成后会使用该通道
——
func worker(ctrl chan<- bool, in <-chan *Work, out chan<- *Work) {
for w := range in {
st := time.Now()
time.Sleep(time.Duration(rand.Int63n(int64(200 * time.Millisecond))))
w.ts = time.Since(st)
out <- w
}
ctrl <- true
}
func control(ctrl <-chan bool, numWorkers int, out chan<- *Work) {
for i=0; i<numWorkers; i++ {
<-ctrl
}
close(out)
}
原答案:
你做一个range完成:
for w := range completed {
log.Printf("job %d completed in %s", w.id, w.ts)
}
但那个频道永远不会关闭
- 1 回答
- 0 关注
- 217 浏览
添加回答
举报
0/150
提交
取消