在 Go 語言中,使用帶緩沖的通道(buffered channels)可以有效地控制并發數。帶緩沖的通道可以讓你限制同時運行的 goroutine 數量,從而避免過度并發導致的資源耗盡問題。以下是一個使用帶緩沖通道控制并發數的示例:
package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, sem chan struct{}, wg *sync.WaitGroup) {
defer wg.Done()
// 請求一個資源
sem <- struct{}{}
// 模擬耗時操作
fmt.Printf("Worker %d started\n", id)
time.Sleep(2 * time.Second)
fmt.Printf("Worker %d finished\n", id)
// 釋放一個資源
<-sem
}
func main() {
// 定義最大并發數
const maxConcurrency = 3
// 創建帶緩沖的通道,用于限制并發數
sem := make(chan struct{}, maxConcurrency)
// 使用 sync.WaitGroup 等待所有 goroutine 完成
var wg sync.WaitGroup
// 啟動 10 個 worker
for i := 1; i <= 10; i++ {
wg.Add(1)
go worker(i, sem, &wg)
}
// 等待所有 worker 完成
wg.Wait()
}
在這個示例中,我們創建了一個帶緩沖的通道 sem,并將其緩沖大小設置為最大并發數。我們使用了一個 sync.WaitGroup 實例來等待所有 goroutine 完成。當 worker 開始執行時,它會向通道發送一個空結構體,從而請求一個資源。如果通道已滿,worker 將會阻塞,直到有可用資源。
當 worker 完成任務后,它會從通道接收一個空結構體,從而釋放一個資源。這樣,我們就可以通過調整 maxConcurrency 的值來控制并發數。