使用等待组完成goroutine

时间:2019-11-12 12:43:35

标签: go

我已经在stdout和stderr goroutine中添加了以下内容(go func()…)以等待获取output并完成error。 现在,我希望外部功能等待,直到两个例程都结束

func exec(stdout io.Reader, stderr io.Reader) (*bufio.Scanner, *bufio.Scanner) {

scanout := bufio.NewScanner(stdout)
scanout.Split(bufio.ScanRunes)
go func() {
    for scanout.Scan() {
        fmt.Print(scanout.Text())
     }
}()

go func() {
scanerr.Split(bufio.ScanRunes)
        for scanerr.Scan() {
            fmt.Print(scanerr.Text())
        }
}()

}


现在,我尝试添加等待组,但由于无法确定如何传递等待组实例而无法正常工作,

func exec(stdout io.Reader, stderr io.Reader) (*bufio.Scanner, *bufio.Scanner) {

scanout := bufio.NewScanner(stdout)
scanout.Split(bufio.ScanRunes)

var waitgroup sync.WaitGroup
waitgroup.Add(1)

go func() {
    for scanout.Scan() {
        fmt.Print(scanout.Text())
     }
}()

waitgroup.Wait()
waitgroup.Add(1)

go func() {
scanerr.Split(bufio.ScanRunes)
        for scanerr.Scan() {
            fmt.Print(scanerr.Text())
        }
}()
waitgroup.Wait()

}

更新

应该是这样吗?

func exec(stdout io.Reader, stderr io.Reader) (*bufio.Scanner, *bufio.Scanner) {

scanout := bufio.NewScanner(stdout)
scanout.Split(bufio.ScanRunes)

var waitgroup sync.WaitGroup
waitgroup.Add(2)

go func() {
    for scanout.Scan() {
        fmt.Print(scanout.Text())
     }
}()

go func() {
scanerr.Split(bufio.ScanRunes)
        for scanerr.Scan() {
            fmt.Print(scanerr.Text())
        }
}()
waitgroup.Wait()

}

1 个答案:

答案 0 :(得分:2)

您不需要将WaitGroup实例传递给goroutine,因为您使用的是function literal,因此可以直接引用在周围函数中声明的变量。

您还可以省略第二个goroutine,在您的用例中并不需要它。

func exec(stdout io.Reader, stderr io.Reader) (*bufio.Scanner, *bufio.Scanner) {
    scanout := bufio.NewScanner(stdout)
    scanout.Split(bufio.ScanRunes)

    var wg sync.WaitGroup
    wg.Add(1)

    // exec scanout in its own goroutine
    go func() {
        for scanout.Scan() {
            fmt.Print(scanout.Text())
        }
        wg.Done()
    }()

    // exec scanerr
    scanerr.Split(bufio.ScanRunes)
    for scanerr.Scan() {
        fmt.Print(scanerr.Text())
    }

    // wait for scanout
    wg.Wait()
}