在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腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!