go - 如何从多个 goroutine 写入同一个 channel

标签 go concurrency

我需要多个 goroutines 在同一个 channel 中写入。然后所有的数据都在一个地方读取,直到所有的 goroutines 完成这个过程。但我不确定关闭此 channel 的最佳方式。

这是我的示例实现:

func main() {
    ch := make(chan data)
    wg := &sync.WaitGroup{}
    for instance := range dataSet {
        wg.Add(1)
        go doStuff(ch, instance)
    }
    go func() {
        wg.Wait()
        close(ch)
    }()

    for v := range ch { //range until it closes
        //proceed v
    }
}

func doStuff(ch chan data, instance data) {
    //do some stuff with instance...
    ch <- instance
}

但我不确定它是不是惯用的。

最佳答案

由于您正在使用 WaitGroup 并在启动新 goroutine 时增加计数器,因此您必须在 goroutine 完成时通过调用 通知 WaitGroup Done() 方法。您还必须将相同的 WaitGroup 传递给 goroutine。您可以通过传递 WaitGroup 的地址来实现。否则每个 goroutine 将使用它自己的 WaitGroup,这将在不同的范围内。

func main() {
    ch := make(chan data)
    wg := &sync.WaitGroup{}
    for _, instance := range dataSet {
        wg.Add(1)
        go doStuff(ch, instance, wg)
    }
    go func() {
        wg.Wait()
        close(ch)
    }()

    for v := range ch { //range until it closes
        //proceed v
    }
}

func doStuff(ch chan data, instance data, wg *sync.WaitGroup) {
    //do some stuff with instance...
    ch <- instance

    // call done method to decrease the counter of WaitGroup
    wg.Done()
}

关于go - 如何从多个 goroutine 写入同一个 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56252711/

相关文章:

go - golang源代码中的g struct define在哪里?

go - 我可以在应用引擎上部署 Golang 应用程序并在不修改代码的情况下读/写文件吗?

java - 是否可以对有界队列使用毒丸方法?

java - 为什么 CompletableFuture.allOf 声明为 CompletableFuture<Void>?

linux - cgo 交叉编译找不到库

go - 同时来自列表的多个随机元素

api - 使用 golang 服务器的第三方 API 的速率限制

java - 原子长操作

go - 在这种情况下,WaitGroup.Wait() 是否意味着内存屏障?

multithreading - 并行收集处理的应用程序设计