等待完成后是否需要创建新的等待组?

时间:2019-02-09 13:01:42

标签: go concurrency

我面临一些并发问题。 我是第一次编写并发应用程序。

我要实现的目标

(使用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)

1 个答案:

答案 0 :(得分:2)

WaitGroups can be safely已重用,但不清楚为什么要为此使用第三方程序包?特别是如果您只是在学习并发性,我强烈建议您坚持使用标准库-sync.WaitGroup是您所需要的。

FWIW,如果我将您的代码修改为使用sync.WaitGroup,它不会死锁并运行到完成-请参见this playground

This Go blog post解释了如何使用通道安全地进行流水线操作,在某些更高级的情况下,请等待组(您并不总是需要它们)