go group并发执行

假如我有100个任务需要执行,但是我只想同时并发40个,因此我想先并发执行前40个,等这40个都执行完了之后在执行40个,等这40个执行完后再执行最后的20个。想到这我就想到了搞一个“协程池”,不知道go有没有类似的开源的协程池项目有?或者有不用协程池也能解决的方案?

阅读 4k
2 个回答
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]
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题