Golang协程池实现
在Golang中实现协程池时遇到几个问题想请教大家:
- 如何优雅地控制协程数量避免资源耗尽?
- 任务队列满了之后应该采用什么策略处理新任务?是直接拒绝还是等待?
- 协程池关闭时如何保证所有任务都能执行完毕?
- 有没有推荐的开源协程池实现可以参考?
- 在协程池中如何收集任务执行结果和错误信息?
2 回复
Golang协程池可通过channel和sync.WaitGroup实现。核心步骤:创建任务队列(channel),启动固定数量的worker协程从队列获取任务执行,使用WaitGroup等待所有任务完成。注意控制并发数和资源回收。
更多关于Golang协程池实现的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go语言中,协程池(goroutine pool)用于控制并发数量,避免无限制创建协程导致资源耗尽。以下是一个简单的协程池实现,包含任务提交、工作协程管理和优雅关闭。
实现步骤:
- 定义任务结构:使用通道传递任务和结果。
- 创建协程池:启动固定数量的工作协程处理任务。
- 提交任务:通过通道发送任务到池中。
- 关闭池:安全关闭通道并等待所有任务完成。
代码示例:
package main
import (
"fmt"
"sync"
)
// 任务结构
type Task struct {
ID int
Data interface{}
}
// 协程池结构
type GoroutinePool struct {
taskChan chan Task // 任务通道
resultChan chan string // 结果通道(可选)
wg sync.WaitGroup
workers int
}
// 创建协程池
func NewGoroutinePool(workers, taskBuffer int) *GoroutinePool {
pool := &GoroutinePool{
taskChan: make(chan Task, taskBuffer),
resultChan: make(chan string, taskBuffer),
workers: workers,
}
pool.start()
return pool
}
// 启动工作协程
func (p *GoroutinePool) start() {
for i := 0; i < p.workers; i++ {
p.wg.Add(1)
go p.worker(i)
}
}
// 工作协程处理任务
func (p *GoroutinePool) worker(id int) {
defer p.wg.Done()
for task := range p.taskChan {
result := fmt.Sprintf("Worker %d processed task %d with data %v", id, task.ID, task.Data)
p.resultChan <- result // 发送结果(根据需求可选)
}
}
// 提交任务
func (p *GoroutinePool) Submit(task Task) {
p.taskChan <- task
}
// 关闭池并等待所有任务完成
func (p *GoroutinePool) Shutdown() {
close(p.taskChan)
p.wg.Wait()
close(p.resultChan)
}
// 获取结果(如果需要)
func (p *GoroutinePool) Results() <-chan string {
return p.resultChan
}
func main() {
// 创建协程池,3个工作协程,任务缓冲区10
pool := NewGoroutinePool(3, 10)
// 提交任务
for i := 1; i <= 5; i++ {
pool.Submit(Task{ID: i, Data: fmt.Sprintf("data-%d", i)})
}
// 关闭池并处理结果
go func() {
pool.Shutdown()
}()
// 读取结果
for result := range pool.Results() {
fmt.Println(result)
}
}
关键点说明:
- 任务通道:缓冲任务,控制并发数。
- WaitGroup:确保所有工作协程在关闭前完成任务。
- 优雅关闭:先关闭任务通道,再等待协程退出。
可根据需求扩展错误处理、动态调整协程数等功能。

