Golang协程池实现

在Golang中实现协程池时遇到几个问题想请教大家:

  1. 如何优雅地控制协程数量避免资源耗尽?
  2. 任务队列满了之后应该采用什么策略处理新任务?是直接拒绝还是等待?
  3. 协程池关闭时如何保证所有任务都能执行完毕?
  4. 有没有推荐的开源协程池实现可以参考?
  5. 在协程池中如何收集任务执行结果和错误信息?
2 回复

Golang协程池可通过channel和sync.WaitGroup实现。核心步骤:创建任务队列(channel),启动固定数量的worker协程从队列获取任务执行,使用WaitGroup等待所有任务完成。注意控制并发数和资源回收。

更多关于Golang协程池实现的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,协程池(goroutine pool)用于控制并发数量,避免无限制创建协程导致资源耗尽。以下是一个简单的协程池实现,包含任务提交、工作协程管理和优雅关闭。

实现步骤:

  1. 定义任务结构:使用通道传递任务和结果。
  2. 创建协程池:启动固定数量的工作协程处理任务。
  3. 提交任务:通过通道发送任务到池中。
  4. 关闭池:安全关闭通道并等待所有任务完成。

代码示例:

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:确保所有工作协程在关闭前完成任务。
  • 优雅关闭:先关闭任务通道,再等待协程退出。

可根据需求扩展错误处理、动态调整协程数等功能。

回到顶部