使用goroutine併發處理工作時,使用channel限制goroutine數量上限。
主要是利用buffered channel與其阻塞,以及可在不同goroutine間溝通的特性來實現。
範例
下面範例利用channel限制goroutine最多只有2條,2條goroutine未結束前會阻塞來避免建立新的goroutine。
main.go
package main
import (
"fmt"
"sync"
"time"
)
func main() {
nums := []int{1, 2, 3, 4, 5} // 要被處理的多筆工作
limit := 2 // goroutine數量限制
ch := make(chan struct{}, limit) // Buffered channel,透過其阻塞特性來控制goroutine數量
wg := sync.WaitGroup{}
for i := 0; i < len(nums); i++ {
ch <- struct{}{} // 值送至channel,滿時阻塞
wg.Add(1) // WaitGroup加計一個goroutine
go func(i int) { // 建立新的goroutine來處理工作
defer func() {
<-ch // 工作處理完後將channel中的值取出,解除上面送入channel的阻塞
wg.Done() // WaitGroup減計一個goroutine
}()
time.Sleep(1 * time.Second) // 模擬耗時工作
fmt.Println(i)
}(nums[i]) // 將工作傳入goroutine處理
}
wg.Wait() // WaitGroup等待所有goroutine執行完
close(ch)
fmt.Println("finished")
}
沒有留言:
張貼留言