等待n goroutines的终止

lhk*_*lhk 10 concurrency channel go coroutine goroutine

我需要开始大量的goroutines并等待他们的终止.直观的方式似乎使用一个频道等待所有这些都完成:

package main

type Object struct {
    //data
}

func (obj *Object) Update(channel chan int) {
    //update data
    channel <- 1
    return
}

func main() {

    channel := make(chan int, n)
    list := make([]Object, n, m)
    for {
        for _, object := range list {
            go object.Update(channel)
        }
        for i := 0; i < n; i++ {
            <-channel
        }
        //now everything has been updated. start again
    }
}
Run Code Online (Sandbox Code Playgroud)

但问题是对象的数量以及因此可能会改变goroutines的数量.是否可以更改通道的缓冲区大小?

有没有更优雅的方式来做到这一点?

bea*_*mit 30

我使用WaitGroup作为解决这个问题的方法.翻译您当前的代码,使用一些日志来清楚发生了什么:

package main

import "sync"
import "fmt"
import "time"

type Object struct {
    //data
}

func (obj *Object) Update(wg *sync.WaitGroup) {
    //update data
    time.Sleep(time.Second)
    fmt.Println("Update done")
    wg.Done()
    return
}

func main() {
    var wg sync.WaitGroup
    list := make([]Object, 5)
    for {
        for _, object := range list {
            wg.Add(1)
            go object.Update(&wg)
        }
        //now everything has been updated. start again
        wg.Wait()
        fmt.Println("Group done")
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案!我可能会在`Update`的开头放置`defer wg.Done()`,以防函数增长并在将来某个时间获得早期返回. (8认同)