go waitgroup 的坑

本文阅读 1 分钟
首页 golang 正文

答案1:

1、waitGroup对象做值传递

如:
func main(){
    var swg sync.WaitGroup
    for i:=0;i<3;i++{
        swg.Add(1)
        go func(wg sync.WaitGroup,mark int){
            defer wg.Done()
            fmt.Printf("%d goroutine finish 
",mark)
        }(swg,i)
    }
    swg.Wait()
}
//运行结果:
//    0 goroutine finish 
//    1 goroutine finish 
//    2 goroutine finish 
//    fatal error: all goroutines are asleep - deadlock!

​ 子协程中传入的waitGroup对象的一份新值拷贝,在main主协程的waitGroup对象并没有被调用Done()方法,导致标志位无法被释放,最后发生死锁。

​ 所以,将waitGroup对象做参数传递时,使用其引用拷贝传入。

2、仅在子协程goroutine中进行add操作

​ 如:

func main() {
    wg := sync.WaitGroup{}
    for i := 0; i < 5; i++ {
        go func(wg *sync.WaitGroup, i int) {
            wg.Add(1)
            log.Printf("i:%d", i)
            wg.Done()
        }(&wg, i)
    }
    wg.Wait()
    log.Println("exit")
}
//运行结果(可能出现):
//    2022/05/09 09:38:36 exit

​ 因为子协程跟main主协程同步进行,可能子协程中还没来得及add(1),mian主线程就已经执行结束了。

​ 所以,尽量不要仅在子协程中进行add操作。

本文来自投稿,不代表本站立场,如若转载,请注明出处:
如何限制 goroutine 并发数量 (channel 或 WaitGroup)
« 上一篇 09-17
分片键的选择?
下一篇 » 09-17

发表评论

发表评论