Go语言Goroutine池详解

王者杯·14天创作挑战营·第8期 10w+人浏览 453人参与

🏊‍♂️ Goroutine 池详解
什么是 Goroutine 池?
Goroutine 池是一种管理并发任务的模式,通过预先创建固定数量的 goroutine 来处理任务,避免无限制创建 goroutine 带来的资源消耗和性能问题。

🎯 核心优势
‌资源控制‌:限制并发 goroutine 数量
‌性能优化‌:复用 goroutine,减少创建销毁开销
‌任务调度‌:有序处理大量并发任务

概述
Goroutine池是一种管理和复用Goroutine的技术,可以有效控制并发数量、减少Goroutine创建和销毁的开销,提高程序性能和稳定性。结合您之前了解的‌闭包‌和‌通道‌特性,Goroutine池能够更好地管理并发任务。

Goroutine池的核心设计

  1. 基本结构
    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 开发规范。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bing.shao

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

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

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

打赏作者

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

抵扣说明:

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

余额充值