当前位置: 首页 > article >正文

如何在Golang中实现协程池

在Golang中实现协程池(Goroutine Pool)可以提高并发任务的执行效率,特别是在需要限制并发数量或管理资源的情况下。协程池允许你控制同时运行的协程数量,从而避免创建过多的协程导致系统资源耗尽。

以下是一个简单的协程池实现示例:

  1. 定义协程池结构体
    协程池结构体需要包含任务队列、工作协程数量、等待组等。

  2. 实现任务提交和协程管理
    使用通道(channel)来管理任务队列,并使用等待组(sync.WaitGroup)来等待所有任务完成。

package main

import (
	"fmt"
	"sync"
	"time"
)

// Task represents a unit of work that the goroutine pool will execute.
type Task func()

// GoroutinePool represents a pool of goroutines that can execute tasks.
type GoroutinePool struct {
	tasks      chan Task
	workerPool chan struct{}
	wg         sync.WaitGroup
	maxWorkers int
}

// NewGoroutinePool creates a new goroutine pool with a specified maximum number of workers.
func NewGoroutinePool(maxWorkers int) *GoroutinePool {
	pool := &GoroutinePool{
		tasks:      make(chan Task),
		workerPool: make(chan struct{}, maxWorkers),
		maxWorkers: maxWorkers,
	}

	// Start worker goroutines
	for i := 0; i < maxWorkers; i++ {
		pool.workerPool <- struct{}{}
		go pool.worker()
	}

	return pool
}

// worker is the goroutine that executes tasks from the tasks channel.
func (p *GoroutinePool) worker() {
	for task := range p.tasks {
		task()
		<-p.workerPool // Signal that a worker is available again
	}
}

// Submit adds a task to the goroutine pool.
func (p *GoroutinePool) Submit(task Task) {
	p.wg.Add(1)
	go func() {
		defer p.wg.Done()
		<-p.workerPool // Wait for a worker to be available
		p.tasks <- task
	}()
}

// Wait waits for all submitted tasks to complete.
func (p *GoroutinePool) Wait() {
	p.wg.Wait()
	close(p.tasks) // Close the tasks channel to signal workers to exit
	for range p.workerPool { // Drain the workerPool to ensure all workers have exited
	}
}

func main() {
	// Create a goroutine pool with 3 workers
	pool := NewGoroutinePool(3)

	// Submit some tasks to the pool
	for i := 0; i < 10; i++ {
		taskNum := i
		pool.Submit(func() {
			fmt.Printf("Executing task %d\n", taskNum)
			time.Sleep(time.Second) // Simulate work
		})
	}

	// Wait for all tasks to complete
	pool.Wait()
	fmt.Println("All tasks completed")
}

解释

  1. 结构体定义
    • Task:表示一个任务,是一个无参数的函数。
    • GoroutinePool:包含任务通道 tasks、工作协程控制通道 workerPool、等待组 wg 和最大工作协程数量 maxWorkers
  2. 创建协程池
    • NewGoroutinePool 函数初始化协程池,并启动指定数量的工作协程。
  3. 工作协程
    • worker 方法从 tasks 通道中接收任务并执行,执行完成后将工作协程标记为可用(通过向 workerPool 发送一个空结构体)。
  4. 提交任务
    • Submit 方法将任务添加到任务通道,并等待一个工作协程变为可用。
  5. 等待任务完成
    • Wait 方法等待所有任务完成,并关闭任务通道,确保所有工作协程退出。

使用示例

main 函数中,我们创建了一个包含3个工作协程的协程池,并提交了10个任务。每个任务打印一个消息并模拟1秒的工作。最后,我们等待所有任务完成并打印完成消息。

这个简单的协程池实现可以根据需要进行扩展,例如添加错误处理、任务超时、动态调整工作协程数量等功能。


http://www.kler.cn/a/465629.html

相关文章:

  • 力扣66 加一
  • 【CSS】 ---- CSS 实现图片背景清除的滑动效果三种方法
  • 鸿蒙应用开发(2)
  • 你喜欢看哪类的网上视频教程?
  • 2025/1/4期末复习 密码学 按老师指点大纲复习
  • dbeaver导入导出数据库(sql文件形式)
  • 靶机系列|VULNHUB|DC-3
  • grouped = df.drop(‘name‘, axis=1).groupby(‘team‘)
  • websocket-sharp:.NET平台上的WebSocket客户端与服务器开源库
  • 医学图像分析工具01:FreeSurfer || Recon -all 全流程MRI皮质表面重建
  • 在Windows计算机上打开 HEIC 文件的 6 种有效方法
  • Servlet中映射与部署
  • 形态学:图像处理中的强大工具
  • 数据分析思维(六):分析方法——相关分析方法
  • 关系分类(RC)模型和关系抽取(RE)模型的区别
  • ros2 py文件间函数调用
  • 【vLLM 学习】欢迎来到 vLLM!
  • 使用C#构建一个论文总结AI Agent
  • ImageNet 2.0?自动驾驶数据集迎来自动标注新时代
  • 知识库召回列表模式揭秘:实现智能信息检索新突破
  • 牛客网刷题 ——C语言初阶——JZ15 二进制中1的个数
  • 服务器数据恢复—服务器硬盘亮黄灯的数据恢复案例
  • 在CE自动汇编里调用lua函数
  • 关于大一上的总结
  • Java实现UDP与TCP应用程序
  • python+PyMuPDF库:(三)pdf文件的选择性合并、其他格式文件转pdf