假如我有100个任务需要执行,但是我只想同时并发40个,因此我想先并发执行前40个,等这40个都执行完了之后在执行40个,等这40个执行完后再执行最后的20个。想到这我就想到了搞一个“协程池”,不知道go有没有类似的开源的协程池项目有?或者有不用协程池也能解决的方案?
###package main
import (
"fmt"
"sync"
)
func main() {
max := 40 // 最大协程数量限制
tasks := 100 // 任务数量
wg := sync.WaitGroup{}
ch := make(chan struct{}, max)
for i := 0; i < tasks; i++ {
wg.Add(1) // 添加计数
ch <- struct{}{} // 写一个标记到 chan,chan缓存满时会阻塞
go func(j int) {
defer func() {
wg.Done() // 将计数减1
<-ch // 读取chan
}()
fmt.Println(j)
}(i)
}
wg.Wait() // 等待加入的协程全部完成
fmt.Println("done...")
}
###可以用channel + waitgroup, 大概思路如下
// 每轮任务个数
const Speed = 40
// 任务总数
const total = 100
// 任务
tasks := make([]interface{}, 0)
taskChan := make(chan interface{}, Speed)
// 已执行任务个数
executedNum := 0
wg := &sync.WaitGroup{}
go func() {
for {
num := total - executedNum
if num <= 0{
return
}
if num > Speed {
executedNum += Speed
num = Speed
}
wg.Add(num)
for i := 0; i < num; i++ {
task := <-taskChan
go func(task interface{}) {
defer wg.Done()
task.Do()
}(task)
}
wg.Wait()
}
}()
for i := 0; i < len(tasks); i++ {
taskChan <- tasks[i]
}