如何在Golang中实现协程池

打印 上一主题 下一主题

主题 802|帖子 802|积分 2406

在Golang中实现协程池(Goroutine Pool)可以进步并发任务的执行服从,特别是在必要限制并发数量或管理资源的环境下。协程池允许你控制同时运行的协程数量,从而制止创建过多的协程导致系统资源耗尽。
以下是一个简朴的协程池实现示例:

  • 定义协程池结构体
    协程池结构体必要包罗任务队列、工作协程数量、期待组等。
  • 实现任务提交和协程管理
    使用通道(channel)来管理任务队列,并使用期待组(sync.WaitGroup)来期待所有任务完成。
  1. package main
  2. import (
  3.         "fmt"
  4.         "sync"
  5.         "time"
  6. )
  7. // Task represents a unit of work that the goroutine pool will execute.
  8. type Task func()
  9. // GoroutinePool represents a pool of goroutines that can execute tasks.
  10. type GoroutinePool struct {
  11.         tasks      chan Task
  12.         workerPool chan struct{}
  13.         wg         sync.WaitGroup
  14.         maxWorkers int
  15. }
  16. // NewGoroutinePool creates a new goroutine pool with a specified maximum number of workers.
  17. func NewGoroutinePool(maxWorkers int) *GoroutinePool {
  18.         pool := &GoroutinePool{
  19.                 tasks:      make(chan Task),
  20.                 workerPool: make(chan struct{}, maxWorkers),
  21.                 maxWorkers: maxWorkers,
  22.         }
  23.         // Start worker goroutines
  24.         for i := 0; i < maxWorkers; i++ {
  25.                 pool.workerPool <- struct{}{}
  26.                 go pool.worker()
  27.         }
  28.         return pool
  29. }
  30. // worker is the goroutine that executes tasks from the tasks channel.
  31. func (p *GoroutinePool) worker() {
  32.         for task := range p.tasks {
  33.                 task()
  34.                 <-p.workerPool // Signal that a worker is available again
  35.         }
  36. }
  37. // Submit adds a task to the goroutine pool.
  38. func (p *GoroutinePool) Submit(task Task) {
  39.         p.wg.Add(1)
  40.         go func() {
  41.                 defer p.wg.Done()
  42.                 <-p.workerPool // Wait for a worker to be available
  43.                 p.tasks <- task
  44.         }()
  45. }
  46. // Wait waits for all submitted tasks to complete.
  47. func (p *GoroutinePool) Wait() {
  48.         p.wg.Wait()
  49.         close(p.tasks) // Close the tasks channel to signal workers to exit
  50.         for range p.workerPool { // Drain the workerPool to ensure all workers have exited
  51.         }
  52. }
  53. func main() {
  54.         // Create a goroutine pool with 3 workers
  55.         pool := NewGoroutinePool(3)
  56.         // Submit some tasks to the pool
  57.         for i := 0; i < 10; i++ {
  58.                 taskNum := i
  59.                 pool.Submit(func() {
  60.                         fmt.Printf("Executing task %d\n", taskNum)
  61.                         time.Sleep(time.Second) // Simulate work
  62.                 })
  63.         }
  64.         // Wait for all tasks to complete
  65.         pool.Wait()
  66.         fmt.Println("All tasks completed")
  67. }
复制代码
解释


  • 结构体定义

    • Task:表示一个任务,是一个无参数的函数。
    • GoroutinePool:包罗任务通道 tasks、工作协程控制通道 workerPool、期待组 wg 和最大工作协程数量 maxWorkers。

  • 创建协程池

    • NewGoroutinePool 函数初始化协程池,并启动指定数量的工作协程。

  • 工作协程

    • worker 方法从 tasks 通道中接收任务并执行,执行完成后将工作协程标志为可用(通过向 workerPool 发送一个空结构体)。

  • 提交任务

    • Submit 方法将任务添加到任务通道,并期待一个工作协程变为可用。

  • 期待任务完成

    • Wait 方法期待所有任务完成,并关闭任务通道,确保所有工作协程退出。

使用示例

在 main 函数中,我们创建了一个包罗3个工作协程的协程池,并提交了10个任务。每个任务打印一个消息并模拟1秒的工作。最后,我们期待所有任务完成并打印完成消息。
这个简朴的协程池实现可以根据必要举行扩展,比方添加错误处理惩罚、任务超时、动态调整工作协程数量等功能。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

兜兜零元

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表