🏊♂️ Goroutine 池详解
什么是 Goroutine 池?
Goroutine 池是一种管理并发任务的模式,通过预先创建固定数量的 goroutine 来处理任务,避免无限制创建 goroutine 带来的资源消耗和性能问题。
🎯 核心优势
资源控制:限制并发 goroutine 数量
性能优化:复用 goroutine,减少创建销毁开销
任务调度:有序处理大量并发任务
概述
Goroutine池是一种管理和复用Goroutine的技术,可以有效控制并发数量、减少Goroutine创建和销毁的开销,提高程序性能和稳定性。结合您之前了解的闭包和通道特性,Goroutine池能够更好地管理并发任务。
Goroutine池的核心设计
- 基本结构
Goroutine池通常包含以下组件:
任务队列:用于存储待处理的任务
工作协程:固定数量的Goroutine处理任务
结果通道:返回处理结果
2. 与通道的关系
基于您之前了解的通道缓冲与不缓冲特性,Goroutine池通常使用缓冲通道作为任务队列,非缓冲通道用于同步控制。
实用Goroutine池实现
以下是一个完整的Goroutine池实现示例
package main
import (
"fmt"
"sync"
"time"
)
// Worker 工作者结构体
type Worker struct {
ID int
Address chan func()
Quit chan bool
}
// Start 启动工作者
func (w *Worker) Start(wg *sync.WaitGroup) {
defer wg.Done()
for {
select {
case job := <-w.Address:
job()
case <-w.Quit:
return
}
}
}
// NewWorker 创建新工作者
func NewWorker(id int) *Worker {
return &Worker{
ID: id,
Address: make(chan func()),
Quit: make(chan bool),
}
}
// Pool 协程池结构体
type Pool struct {
Workers []*Worker
Queue chan func()
Quit chan bool
Wg sync.WaitGroup
}
// NewPool 创建新的协程池
func NewPool(size int) *Pool {
pool := &Pool{
Workers: make([]*Worker, size),
Queue: make(chan func(), 100),
Quit: make(chan bool),
}
for i := 0; i < size; i++ {
worker := NewWorker(i + 1)
pool.Workers[i] = worker
pool.Wg.Add(1)
go worker.Start(&pool.Wg)
}
go pool.dispatcher()
return pool
}
// dispatcher 分发任务到工作者
func (p *Pool) dispatcher() {
for {
select {
case job := <-p.Queue:
go func(job func()) {
freeWorker := p.getFreeWorker()
if freeWorker != nil {
freeWorker.Address <- job
} else {
fmt.Println("No available worker, executing in queue thread")
job()
}
}(job)
case <-p.Quit:
for _, worker := range p.Workers {
worker.Quit <- true
}
p.Wg.Wait()
close(p.Queue)
return
}
}
}
// getFreeWorker 获取空闲工作者
func (p *Pool) getFreeWorker() *Worker {
for _, worker := range p.Workers {
select {
case worker.Address <- func() {}:
return worker
default:
}
}
return nil
}
// Submit 提交任务到协程池
func (p *Pool) Submit(job func()) {
p.Queue <- job
}
// Close 关闭协程池
func (p *Pool) Close() {
close(p.Quit)
}
func main() {
pool := NewPool(3)
defer pool.Close()
for i := 1; i <= 10; i++ {
id := i
pool.Submit(func() {
fmt.Printf("Task %d is running\n", id)
time.Sleep(2 * time.Second)
fmt.Printf("Task %d completed\n", id)
})
}
time.Sleep(25 * time.Second)
}
代码说明:
main.go 实现了一个完整的 Goroutine 池系统,包含工作者管理、任务分发与执行控制等核心功能。
go.mod 文件定义了 Go 模块的基本信息,确保项目结构符合现代 Go 开发规范。
654

被折叠的 条评论
为什么被折叠?



