GO 协程池(任务池)的实现
实现主要来源于:
servicecomb-service-center
- 首先创建一个协程池的结构体,考虑我们所需要的东西
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
| type Task interface{ Run() }
var _ Task =(*sumtask)(nil)
type sumtask struct { a int b int }
func(t *sumtask) Run() { fmt.Println(a + b) }
type Pool struct { idletime time.Duration pending chan Task workers chan struct{} }
|
- 创建构造函数
1 2 3 4 5 6 7
| func NewPool(sz int) *Pool { return &Pool{ pending: make(chan Task), workers: make(chan struct{}, sz), idleTime: 3 * time.Second, } }
|
- 任务分发函数
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
| func (p *Pool) Do(task Task) { select { case p.pending <- task: case p.worker <- struct{}{}: go p.loop(task) } }
func (p *Pool) loop(task Task) { timer := time.NewTimer(p.idleTime) for { task.Run() select{ case <- timer.C: fmt.Println("goroutine idle,and return") return case task = <- p.pending: timer.Stop() timer.Reset(p.idleTime) } } }
|
- 测试一下
1 2 3 4 5 6 7 8 9 10 11 12 13
| func main() { p := NewPool(10) task = sumtask{ a : 1, b : 2, }
for i:=0; i< 20; i++ { p.Do(&task) }
time.Sleep(20 * time.Second) }
|