我面临一些并发问题。 我是第一次编写并发应用程序。
(使用goroutines)相关函数(即func2
取决于func1
的结果
如果我在等待组完成后重用了等待,则会收到错误消息
fatal error: all goroutines are asleep - deadlock!
这是我的代码(Playground):
package main
import (
"fmt"
"sync"
"time"
)
func main() {
wg := sync.WaitGroup{}
ch := make(chan int)
for a := 0; a < 3; a++ {
wg.Add(1)
go func1(int(3-a), ch, &wg)
}
go func() {
wg.Wait()
close(ch)
}()
//wg2 := sync.WaitGroup{} //<-- If I uncomment this and the corresponding wg2 code, then the snippet runs fine
ch2 := make(chan string)
for val := range ch {
fmt.Println(val)
wg.Add(1)
//wg2.Add(1)
go func2(val, ch2, &wg)
//go func2(val, ch2, &wg2)
}
go func() {
wg.Wait()
//wg2.Wait()
close(ch2)
}()
for val := range ch2 {
fmt.Println(val)
}
}
func func1(seconds int, ch chan<- int, wg *sync.WaitGroup) {
defer wg.Done()
time.Sleep(time.Duration(seconds) * time.Second)
ch <- seconds
}
func func2(seconds int, ch chan<- string, wg *sync.WaitGroup) {
defer wg.Done()
ch <- "hello"
}
因此,您可以看到,如果我创建一个新的WaitGroup
可以正常工作,否则会出现死锁。
谢谢
Temporarya
(Golang Noobie)
答案 0 :(得分:2)
WaitGroups can be safely已重用,但不清楚为什么要为此使用第三方程序包?特别是如果您只是在学习并发性,我强烈建议您坚持使用标准库-sync.WaitGroup
是您所需要的。
FWIW,如果我将您的代码修改为使用sync.WaitGroup
,它不会死锁并运行到完成-请参见this playground
This Go blog post解释了如何使用通道安全地进行流水线操作,在某些更高级的情况下,请等待组(您并不总是需要它们)