英文:
Need run a goroutine for WaitGroup in a function
问题
我已经阅读了来自https://go.dev/blog/pipelines的一篇关于管道的文章。
我尝试移除覆盖**wg.Wait()**的goroutine,但结果导致所有的goroutine都处于休眠状态 - 死锁!
我真的不明白为什么会这样。
func merge(cs ...<-chan int) <-chan int {
var wg sync.WaitGroup
out := make(chan int)
// 为cs中的每个输入通道启动一个输出goroutine。output将值从c复制到out,直到c关闭,然后调用wg.Done。
output := func(c <-chan int) {
for n := range c {
out <- n
}
wg.Done()
}
wg.Add(len(cs))
for _, c := range cs {
go output(c)
}
// 启动一个goroutine,在所有输出goroutine完成后关闭out。这必须在wg.Add调用之后启动。
go func() {
wg.Wait()
close(out)
}()
return out
}
英文:
I've read a pipeline article from https://go.dev/blog/pipelines.
I've tried to remove the goroutine that covers wg.Wait() but it turns out that caused all goroutines are asleep - deadlock!
I really don't understand why.
func merge(cs ...<-chan int) <-chan int {
var wg sync.WaitGroup
out := make(chan int)
// Start an output goroutine for each input channel in cs. output
// copies values from c to out until c is closed, then calls wg.Done.
output := func(c <-chan int) {
for n := range c {
out <- n
}
wg.Done()
}
wg.Add(len(cs))
for _, c := range cs {
go output(c)
}
// Start a goroutine to close out once all the output goroutines are
// done. This must start after the wg.Add call.
go func() {
wg.Wait()
close(out)
}()
return out
}
答案1
得分: 1
out
是一个阻塞通道。你需要 return out
并让某个东西从 out
中消费,否则 output
协程在尝试写入任何内容时都会被阻塞。如果 merge
在消费者甚至有机会开始之前就等待等待组(即等待所有任务完成),那就是一个不可避免的死锁。
英文:
out
is a blocking channel. You need to return out
and let something consume from out
, or else the output
goroutines will block as soon as they try to write anything. If merge
waits on the waitgroup (i.e. waits for everything to finish) before the consumer even has a chance to start, that's an inevitable deadlock.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论