实现 Limit 并发控制

🔴 困难

题目描述

实现一个 Limit 函数,限制最多 n 个 goroutine 并发执行。

参考答案

func Limit(n int, tasks []func()) {
    sem := make(chan struct{}, n)
    var wg sync.WaitGroup
    
    for _, task := range tasks {
        wg.Add(1)
        sem <- struct{}{} // 获取信号量
        
        go func(f func()) {
            defer wg.Done()
            defer func() { <-sem }() // 释放信号量
            f()
        }(task)
    }
    
    wg.Wait()
}

使用示例

tasks := []func(){
    func() { fmt.Println("task 1") },
    func() { fmt.Println("task 2") },
    func() { fmt.Println("task 3") },
}

Limit(2, tasks) // 最多 2 个并发

关键点

  1. 缓冲 channel 作为信号量:容量为 n
  2. 发送操作阻塞:超过 n 个 goroutine 时阻塞
  3. defer 释放:确保信号量一定被释放