我需要开始大量的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
    }
}

但问题是,对象的数量以及goroutine的数量可能会发生变化.是否可以更改通道的缓冲区大小?

有没有更优雅的方式来做这件事呢?

推荐答案

我用WaitGroup来解决这个问题.翻译您当前的代码,并使用一些日志(log)来清楚地说明正在发生的事情:

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")
    }
}

Go相关问答推荐

Go编译器标志-修剪路径不完全工作

在字符串与字符串子切片上使用len进行位转移产生意外输出

理解Golang并发:缓冲通道的意外行为

在不耗尽资源的情况下处理S3文件下载

Websocket服务器实现与x/net库trowing 403

如何使redis池的等待超时

`docker system df` 与 `/system/df` (docker api 端点)

Fizz对Gin的OpenAPI生成器正在重命名类型

Golang校验器包:重命名字段错误处理

为什么我只收到部分错误而不是我启动的 goroutines 的所有错误?

同一文件上的多个 Arrow CSV 阅读器返回 null

获取 nil 指针类型的 reflect.Value

判断一个区域内的纬度/经度点

GqlGen - 在字段解析器中访问查询输入参数

如何将多个切片打印为一个切片?

GORM GIN 更新查询导致 500 内部服务器错误

如何在 Unmarshal 中使用泛型(转到 1.18)

使用 LoadLibraryA(path_to_dll) 加载 DLL 会将文件描述符 0、1 和 2 的继承句柄标志 (HANDLE_FLAG_INHERIT) 从 1 更改为 0

处理程序中的无限循环

Go/Golang:如何从 big.Float 中提取最低有效数字?