一文搞懂goroutine控制并发数量的方式

2023-12-09 22:53:55 浏览数 (1)

在Go语言中,可以使用goroutine和channel来控制并发数量。下面我将介绍两种常见的方法:

使用WaitGroup:WaitGroup是Go语言中的一个并发原语,可以用于等待一组goroutine完成执行。通过在启动goroutine之前,使用Add方法增加等待组的计数器,并在goroutine执行完毕后使用Done方法减少计数器,可以判断当前执行的goroutine数量。结合Wait方法,可以在一定数量后停止启动新的goroutine。

下面是一个示例代码:

代码语言:go复制
package main  
  
import (  
 "fmt"  
 "sync"  
)  
  
func main() {  
 var wg sync.WaitGroup  
 maxConcurrency := 5  
 wg.Add(maxConcurrency)  
  
 for i := 0; i < maxConcurrency; i   {  
 go func() {  
 defer wg.Done()  
 // 模拟耗时操作  
 fmt.Println("Goroutine started")  
 // 假设这里是一些需要并发执行的任务  
 }()  
 }  
  
 wg.Wait()  
 fmt.Println("All goroutines have completed")  
}

在上面的示例中,我们使用sync.WaitGroup来控制并发数量,通过设置maxConcurrency变量来限制并发数量为5。在启动每个goroutine之前,我们使用wg.Add(maxConcurrency)增加计数器,并在goroutine执行完毕后使用wg.Done()减少计数器。最后,我们使用wg.Wait()等待所有goroutine执行完毕。

使用带缓冲的channel:另一种常见的方法是使用带缓冲的channel来控制并发数量。通过设定channel的缓冲区大小,可以限制同时运行的goroutine数量。当缓冲区满时,后续的goroutine会被阻塞直到有空间可用。

下面是一个示例代码:

代码语言:go复制
package main  
  
import "fmt"  
  
func main() {  
 maxConcurrency := 5  
 concurrencyChan := make(chan struct{}, maxConcurrency)  
  
 for i := 0; i < maxConcurrency; i   {  
 concurrencyChan <- struct{}{} // 向channel发送信号,占用一个缓冲区位置  
 go func() {  
 defer func() { <-concurrencyChan }() // 从channel接收信号,释放一个缓冲区位置  
 // 模拟耗时操作  
 fmt.Println("Goroutine started")  
 // 假设这里是一些需要并发执行的任务  
 }()  
 }  
  
 // 等待所有goroutine完成  
 for i := 0; i < maxConcurrency; i   {  
 <-concurrencyChan // 从channel接收信号,等待goroutine完成并释放缓冲区位置  
 }  
}

在上面的示例中,我们创建了一个带缓冲大小为maxConcurrency的channel。在启动每个goroutine之前,我们向channel发送一个信号,占用一个缓冲区位置。在goroutine执行完毕后,我们从channel接收信号,释放一个缓冲区位置。最后,我们通过循环从channel接收信号,等待所有goroutine完成并释放缓冲区位置。

我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!

0 人点赞