go-study/routine/pool.go

67 lines
1019 B
Go
Raw Normal View History

2023-12-23 14:33:52 +08:00
package routine
import (
"sync"
)
2023-12-28 14:58:06 +08:00
type Pool struct {
2023-12-26 16:07:46 +08:00
taskQueue chan T
taskFn func(T)
workers int
panicHandler func(any)
wg sync.WaitGroup
2023-12-23 14:33:52 +08:00
}
2023-12-28 14:58:06 +08:00
func NewPool(opt ...Option) *Pool {
opts := loadOptions(opt...)
pool := &Pool{
2023-12-26 16:07:46 +08:00
taskQueue: make(chan T, opts.capacity),
panicHandler: opts.panicHandler,
workers: opts.workers,
}
pool.taskFn = func(t T) {
defer func() {
// 处理协程运行中出现panic的情况
if r := recover(); r != nil {
if pool.panicHandler != nil {
pool.panicHandler(r)
2023-12-23 14:33:52 +08:00
}
2023-12-26 16:07:46 +08:00
}
}()
2023-12-23 14:33:52 +08:00
2023-12-26 16:07:46 +08:00
opts.taskFn(t)
2023-12-23 14:33:52 +08:00
}
2023-12-26 16:07:46 +08:00
pool.wg.Add(opts.workers)
2023-12-23 14:33:52 +08:00
return pool
}
// Start 启动任务
2023-12-28 14:58:06 +08:00
func (p *Pool) Start() {
2023-12-23 14:33:52 +08:00
for i := 0; i < p.workers; i++ {
go func() {
defer p.wg.Done()
for {
task, ok := <-p.taskQueue
if !ok {
return
}
p.taskFn(task)
}
}()
}
}
// Push 提交任务
2023-12-28 14:58:06 +08:00
func (p *Pool) Push(task T) {
2023-12-23 14:33:52 +08:00
p.taskQueue <- task
}
// Wait 挂起当前协程
2023-12-28 14:58:06 +08:00
func (p *Pool) Wait() {
2023-12-23 14:33:52 +08:00
close(p.taskQueue)
p.wg.Wait()
}