利用带缓存的channel和WaitGroup, 可以实现对goroutine的并发数控制. 使用起来非常简单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package main
import ( "fmt" "sync" )
func httpGet(url string, limiter chan bool, wg *sync.WaitGroup) { defer wg.Done() fmt.Println("http get:", url) <- limiter }
func main() { wg := &sync.WaitGroup{} limiter := make(chan bool, 20)
for i := 0; i < 99; i++ { wg.Add(1) limiter <- true go httpGet(string(i), limiter, wg) } wg.Wait() fmt.Println("所有协程已执行完毕") }
|
带缓存channel的特性, 当缓存被填满时, for循环中最新一次迭代将阻塞到 limiter <- true
这一行中, 当有其他goroutine执行完毕, 会主动消费limiter
中的一个元素, 这样就腾出了一个新的坑位, 之前停留在 limiter <- true
的代码会继续向下执行, 继续循环迭代