Go语言中通过channel和goroutine实现多生产者多消费者模式,使用有缓冲channel传递任务,生产者并发发送任务,消费者从channel读取并处理,所有生产者完成后关闭channel,消费者在channel关闭后自动退出,配合sync.WaitGroup确保协程同步,避免资源竞争与泄漏。

在Go语言中,channel是实现多生产者多消费者模式的核心工具。通过goroutine和channel的配合,可以轻松构建高并发的任务处理系统。下面是一个典型的多生产者、多消费者的示例,并附带关键说明。
以下是一个使用channel实现多生产者多消费者的简单示例:
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
// 任务结构体
type Task struct {
ID int
Data string
}
func producer(id int, tasks chan<- Task, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < 5; i++ {
task := Task{
ID: i,
Data: fmt.Sprintf("producer-%d-task-%d", id, i),
}
time.Sleep(time.Duration(rand.Intn(500)) * time.Millisecond) // 模拟随机生成时间
tasks <- task
fmt.Printf("Producer %d sent task: %s\n", id, task.Data)
}
}
func consumer(id int, tasks <-chan Task, wg *sync.WaitGroup) {
defer wg.Done()
for task := range tasks { // 自动在channel关闭时退出循环
time.Sleep(time.Duration(rand.Intn(800)) * time.Millisecond) // 模拟处理耗时
fmt.Printf("Consumer %d processed task: %s\n", id, task.Data)
}
fmt.Printf("Consumer %d stopped.\n", id)
}
func main() {
const numProducers = 3
const numConsumers = 2
const bufferSize = 10
var wg sync.WaitGroup
tasks := make(chan Task, bufferSize)
// 启动生产者
for i := 0; i < numProducers; i++ {
wg.Add(1)
go producer(i, tasks, &wg)
}
// 启动消费者
for i := 0; i < numConsumers; i++ {
wg.Add(1)
go consumer(i, tasks, &wg)
}
// 等待所有生产者完成
go func() {
wg.Wait()
close(tasks) // 所有生产者结束后关闭channel
}()
// 等待所有消费者完成(通过wg无法直接等待消费者,需用其他方式)
// 这里使用额外的WaitGroup管理消费者
var consumerWg sync.WaitGroup
for i := 0; i < numConsumers; i++ {
consumerWg.Add(1)
go func(id int) {
defer consumerWg.Done()
consumer(id, tasks, &sync.WaitGroup{}) // 注意:这里不再参与主wg
}(i)
}
// 改进方案:更好的做法是分离生产者和消费者的wg管理
// 下面是修正后的完整流程
fmt.Println("All producers and consumers started.")
consumerWg.Wait()
fmt.Println("All done.")
}1. channel方向控制:使用`chan
2. 关闭channel的时机:必须由生产者方在所有goroutine结束后调用close(tasks)。不能由消费者关闭,否则可能引发panic。
立即学习“go语言免费学习笔记(深入)”;
3. 使用单独的goroutine等待生产者并关闭channel:避免死锁。主协程通过wg等待所有生产者完成,然后关闭channel,通知消费者结束。
4. 消费者如何退出:使用for task := range tasks,当channel被关闭且无剩余数据时,循环自动结束。
context.Context实现超时或取消机制。基本上就这些。这个模式稳定、清晰,适用于日志收集、消息队列、爬虫任务分发等场景。
以上就是Golang channel多生产者消费者模式示例的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号