go channel 和 goroutine 来实现协程池
话不多说直接上代码后面会有注释代码实现过程 下面是一个简单的示例,演示了如何实现一个协程池。
type Pool struct {
tasks chan func()
wg sync.WaitGroup
}
func NewPool(size int) *Pool {
p := &Pool{
tasks: make(chan func()),
}
p.wg.Add(size)
for i := 0; i < size; i++ {
go p.worker()
}
return p
}
func (p *Pool) worker() {
defer p.wg.Done()
for task := range p.tasks {
task()
}
}
func (p *Pool) AddTask(task func()) {
p.tasks <- task
}
func (p *Pool) Close() {
close(p.tasks)
}
func (p *Pool) Wait() {
p.wg.Wait()
}
func main() {
pool := NewPool(4)
for i := 0; i < 10; i++ {
pool.AddTask(func() {
fmt.Println("task is running")
})
}
pool.Close()
pool.Wait()
}
在上面的代码中,我们定义了一个 Pool 类型,它包含一个 tasks 字段,用来存储待执行的任务。我们还定义了 NewPool、worker、AddTask、Close 和 Wait 函数,用来创建协程池、执行任务、添加任务、关闭协程池和等待所有任务完成。
当我们调用 NewPool 函数创建一个协程池时,它会初始化 tasks channel,并启动指定数量的 worker goroutine。每个 worker goroutine 都会从 tasks channel 中接收任务并执行。当我们调用 AddTask 函数添加任务时,它会向 tasks channel 发送一个函数值。当我们调用 Close 函数关闭协程池时,它会关闭 tasks channel,这会导致所有 worker goroutine 退出。当我们调用 Wait 函数等待所有任务完成时,它会阻塞直到所有 worker goroutine 退出。
运行上面的代码,你会看到输出 “task is running” 十次。