Skip to content

Instantly share code, notes, and snippets.

@haozibi
Last active August 29, 2019 07:54
Show Gist options
  • Save haozibi/9e65a39ae8944012fc1233ff9d756c75 to your computer and use it in GitHub Desktop.
Save haozibi/9e65a39ae8944012fc1233ff9d756c75 to your computer and use it in GitHub Desktop.
简陋的协程池
package main
import (
"fmt"
"sync"
)
// https://play.golang.org/p/jooMMwYID54
// 一个简单的协程池
// 关键问题是:range 读取 closed retCh 时才不会报错
// 何时关闭 retCh 才是关键,我修改原始代码增加了 WaitGroup
// https://mp.weixin.qq.com/s/fINhzg3eNi9YFi5qZ_JzGA
func main() {
totalTask := 20
var wg sync.WaitGroup
wg.Add(totalTask)
jobCh := make(chan int, totalTask)
go func() {
for i := 0; i < totalTask; i++ {
jobCh <- i
}
close(jobCh)
}()
retCh := make(chan string, 20)
// 启动 5 个协程梳理
workerPool(5, jobCh, retCh, &wg)
wg.Wait()
close(retCh)
for ret := range retCh {
fmt.Println(ret)
}
}
// 启动一个协程池
// n 为最多协程数量
// jobCh 为写入队列,协程从 jobCh 读取读取内容
// retCh 为结果队列,协程把结果写入到 retCh 中
func workerPool(n int, jobCh <-chan int, retCh chan<- string, wg *sync.WaitGroup) {
for i := 0; i < n; i++ {
go worker(i, jobCh, retCh, wg)
}
}
func worker(id int, jobCh <-chan int, retCh chan<- string, wg *sync.WaitGroup) {
for job := range jobCh {
ret := fmt.Sprintf("worker %d processed job: %d", id, job)
retCh <- ret
wg.Done()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment