Yuv*_*val 3 concurrency input channel go output
我尝试遵循 Rob Pike 在演讲“并发不是并行性”中的例子,做了这样的事情:我启动了许多 go 例程,作为从输入通道读取数据的工作程序,执行一些处理,然后通过输出通道发送结果。
然后我启动另一个 go 例程,从某个源读取数据并通过工作人员的输入通道将其发送给工作人员。最后,我想迭代输出通道中的所有结果并用它们做一些事情。问题是,因为工作是在工作人员之间分配的,所以我不知道所有工作人员何时完成,因此我可以停止向输出通道询问更多结果,并且我的程序可以正常结束。
了解工作人员何时完成将结果发送到输出通道的最佳实践是什么?
我个人喜欢使用 async.WaitGroup
来实现这一点。waitgroup 是一个同步计数器,具有三个方法 - Wait()
、Done()
和Add()
。您要做的就是增加等待组的计数器,将其传递给工作人员,并让他们Done()
在完成后调用。然后,您只需阻塞另一端的等待组,并在全部完成后关闭输出通道,从而导致输出处理器退出。
基本上:
// create the wait group
wg := sync.WaitGroup{}
// this is the output channel
outchan := make(chan whatever)
// start the workers
for i := 0; i < N; i++ {
wg.Add(1) //we increment by one the waitgroup's count
//the worker pushes data onto the output channel and calls wg.Done() when done
go work(&wg, outchan)
}
// this is our "waiter" - it blocks until all workers are done and closes the channel
go func() {
wg.Wait()
close(outchan)
}()
//this loop will exit automatically when outchan is closed
for item := range outchan {
workWithIt(item)
}
// TADA!
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1680 次 |
最近记录: |