首页 > 后端开发 > Golang > 使用缓冲通道作为信号量时如何确保所有 Goroutine 完成?

使用缓冲通道作为信号量时如何确保所有 Goroutine 完成?

Susan Sarandon
发布: 2024-12-02 00:54:13
原创
555 人浏览过

How Can I Ensure All Goroutines Finish When Using a Buffered Channel as a Semaphore?

使用WaitGroup等待缓冲通道为空

在并发编程中,通常需要控制并发执行的goroutines的数量。一种常见的方法是使用缓冲通道作为信号量。但是,请务必注意此方法的局限性。

考虑以下示例:

ints := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
 sem := make(chan struct{}, 2)
for _, i := range ints {
  sem<- struct{}{}
  go func(id int, sem chan struct{}) {
    // do something
    <-sem
  }(i, sem)
}
登录后复制

此代码使用大小为 2 的缓冲通道 (sem) 来限制并发数量goroutine 变为 2。但是,有一个问题:程序可能会在最后几个 goroutine 完成其任务之前结束。这是因为缓冲通道在处理过程中的任何时候都可能变空,即使程序正在调度更多的 goroutine。

要等待缓冲通道耗尽,我们不能依赖通道本身。相反,我们可以使用sync.WaitGroup来跟踪未完成的goroutines的数量:

sem := make(chan struct{}, 2)
var wg sync.WaitGroup
for _, i := range ints {
  wg.Add(1)
  sem<- struct{}{}
  go func(id int) {
    defer wg.Done()
    // do something
    <-sem
  }(i)
}
wg.Wait()
登录后复制

在这个修改后的代码中,我们在分派每个goroutine之前使用wg.Add(1)来增加等待组。当 goroutine 完成其任务时,defer wg.Done() 语句会递减等待组。最后,wg.Wait() 会阻塞,直到等待组达到零,以确保所有 goroutine 都已完成执行。这种方法允许我们等待通道耗尽并确保程序不会过早终止。

以上是使用缓冲通道作为信号量时如何确保所有 Goroutine 完成?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板