控制协程的并发数量
控制协程的并发数量
1 并发过多
一个例子:
func main() {
var wg sync.WaitGroup
for i := 0; i < math.MaxInt32; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
fmt.Println(i)
time.Sleep(time.Second)
}(i)
}
wg.Wait()
}
这个例子实现了math.MaxInt32个协程的并发,大约2^31 = 2亿个。
2 如何解决
不同的应用程序,消耗的资源是不一样的。比较推荐的方式的是:应用程序来主动限制并发的协程数量。
2.1 利用channel的缓冲区
可以利用信道channel的缓冲区大小来实现。
// main_chan.go
func main() {
var wg sync.WaitGroup
ch := make(chan struct{}, 3)
for i := 0; i < 10; i++ {
ch <- struct{}{}
wg.Add(1)
go func(i int) {
defer wg.Done()
log.Println(i)
time.Sleep(time.Second)
<-ch
}(i)
}
wg.Wait()
}
每秒控制3个协程并发。
2.2 利用第三方库的协程池
目前有很多第三方库实现了协程池,可以很方便地用来控制协程的并发数量,比较受欢迎的有: