首页 > 文章列表 > 如何使用 Go 语言限制并发执行的任务数量,并保证每次最多只执行 40 个任务?

如何使用 Go 语言限制并发执行的任务数量,并保证每次最多只执行 40 个任务?

134 2025-02-05

如何使用 Go 语言限制并发执行的任务数量,并保证每次最多只执行 40 个任务?

使用 go 限制并发执行的任务

如何在 go 中并发执行任务,同时控制并发数量是一个常见的问题。这个问题要求限制并发执行 100 个任务的数量,每次最多只执行 40 个。

协程池解决方案

一个可行的解决方案是使用协程池。协程池是一个预分配协程集合,可以用来并行执行任务。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...")
}

在这个例子中:

  • max: 指定并发协程的最大数量。
  • tasks: 指定要执行的任务总数。
  • wg: 等待组,用于跟踪正在运行的协程数。
  • ch:一个容量为 max 的通道,用于限制并发协程数量。

程序的工作原理如下:

  1. 主协程创建 ch 通道并设置容量为 max。
  2. 主协程循环创建任务,每个任务都用一个独立的协程运行。
  3. 在创建每个任务时,主协程将一个标记写入 ch 通道。
  4. 如果 ch 通道已满,发送到 ch 的操作将会被阻塞,直到有空位可用。
  5. 每个任务协程完成其任务后,它会从 wg 中减去 1,并从 ch 中读取一个标记。
  6. 主协程等待 wg 达到 0,这表示所有任务都已完成。
来源:1730213612