Go 线程池实现案例

Go 语言并不像其他一些语言(例如 Java 或 C#)那样直接提供一个线程池的概念。相反,Go 使用 goroutines 来实现并发,它是一种比线程更轻量级的并发执行单元。不过,仍然可以实现一个类似线程池的结构,来管理和限制同时运行的 goroutines 的数量。以下是如何在 Go 中实现一个简单的类似线程池的功能的例子:

go 复制代码
package main

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

// WorkerPool 结构体定义
type WorkerPool struct {
	jobs    chan func()   // 用于接收任务的通道
	maxJobs int           // 最大并发任务数
	wg      sync.WaitGroup // 用于等待所有任务完成
}

// NewWorkerPool 创建一个新的 WorkerPool
func NewWorkerPool(maxJobs int) *WorkerPool {
	pool := &WorkerPool{
		jobs:    make(chan func(), maxJobs),
		maxJobs: maxJobs,
	}
	return pool
}

// Start 开始 WorkerPool 的工作
func (p *WorkerPool) Start() {
	for i := 0; i < p.maxJobs; i++ {
		go func() {
			for job := range p.jobs {
				job()
			}
		}()
	}
}

// Submit 提交一个任务到 WorkerPool
func (p *WorkerPool) Submit(job func()) {
	p.wg.Add(1)
	p.jobs <- func() {
		defer p.wg.Done()
		job()
	}
}

// Wait 等待所有任务完成
func (p *WorkerPool) Wait() {
	p.wg.Wait()
	close(p.jobs) // 关闭通道,停止接收新的任务
}

func main() {
	// 创建一个最大并发数为 3 的工作池
	pool := NewWorkerPool(3)
	pool.Start()

	for i := 0; i < 10; i++ {
		i := i // 创建任务变量的本地副本
		pool.Submit(func() {
			fmt.Printf("Starting job %d\n", i)
			time.Sleep(2 * time.Second) // 模拟耗时操作
			fmt.Printf("Finished job %d\n", i)
		})
	}

	// 等待所有任务完成
	pool.Wait()
	fmt.Println("All jobs completed.")
}

在这个例子中,WorkerPool 结构体有一个 jobs 通道用于接收任务,一个 maxJobs 表示最大并发任务数,和一个 sync.WaitGroup 用于等待所有任务完成。Start 方法启动了 maxJobs 数量的 goroutines,每个 goroutine 不断地从 jobs 通道中接收并执行任务。Submit 方法用于提交新的任务到 jobs 通道,同时增加 WaitGroup 的计数。Wait 方法等待所有任务完成后关闭 jobs 通道。

main 函数中,创建了一个最大并发数为 3 的 WorkerPool,提交了 10 个任务,然后调用 Wait 方法等待所有任务完成。

这个简单的 WorkerPool 实现可以控制同时运行的 goroutines 数量,从而类似于其他语言中的线程池概念。当然,根据实际需求,你可以扩展和定制这个 WorkerPool 的实现,例如添加任务的优先级、错误处理、任务结果的收集等功能。

相关推荐
用户685453759776936 分钟前
同步成本换并行度:多线程、协程、分片、MapReduce 怎么选才不踩坑
后端
javaTodo43 分钟前
Claude Code 记忆机制详解:从 CLAUDE.md 到 Auto Memory,六层体系全拆解
后端
LSTM971 小时前
使用 C# 和 Spire.PDF 从 HTML 模板生成 PDF 的实用指南
后端
JaguarJack1 小时前
为什么 PHP 闭包要加 static?
后端·php·服务端
BingoGo1 小时前
为什么 PHP 闭包要加 static?
后端
是糖糖啊2 小时前
OpenClaw 从零到一实战指南(飞书接入)
前端·人工智能·后端
百度Geek说2 小时前
基于Spark的配置化离线反作弊系统
后端
Java编程爱好者2 小时前
虚拟线程深度解析:轻量并发编程的未来趋势
后端
苏三说技术3 小时前
Spring AI 和 LangChain4j ,哪个更好?
后端