网络语言系列&go系列【仅供参考】:如何在Golang中实现协程池




如何在Golang中实现协程池

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

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

1. 定义协程池结构体:

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

2. 实现任务提交和协程管理:

使用通道(channel)来管理任务队列,并使用等待组(sync.WaitGroup)来等待所有任务完成。

3. 上代码

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秒的工作。最后,我们等待所有任务完成并打印完成消息。

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







ac-er8888

如何在Golang中实现协程池

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坦笑&&life

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值