当前位置: 首页 > news >正文

go:Producer Consumer Pattern

项目结构:

image

 

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Producer Consumer  Pattern 生产者消费者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 19:31
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : config.go
*/
package config// 配置层
const (QueueMaxSize     = 5MaxProduceCount  = 10 // 最大生产数量,达到后自动停止ProducerThreads  = 1ProcessThreads   = 2QualityThreads   = 1WarehouseThreads = 1SaleThreads      = 2// 模拟耗时(最小,最大)秒TimeRaw          = 1.0TimeRawMax       = 3.0TimeProcess      = 2.0TimeProcessMax   = 4.0TimeQuality      = 1.0TimeQualityMax   = 2.0TimeWarehouse    = 0.5TimeWarehouseMax = 1.0TimeSale         = 1.0TimeSaleMax      = 3.0
)var (RawMaterials  = []string{"黄金原料", "钻石原石", "翡翠原石", "铂金原料"}QualityLevels = []string{"S级(顶级)", "A级(优质)", "B级(普通)"}
)/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Producer Consumer  Pattern 生产者消费者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 19:32
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : utils.go
*/
package utilsimport ("fmt""math/rand""time"
)// 工具层(日志 + 耗时模拟)
func init() {rand.Seed(time.Now().UnixNano())
}// Info 统一日志输出(和 Python 格式一致)
func Info(tag, msg string) {now := time.Now().Format("2006-01-02 15:04:05")fmt.Printf("%s | INFO | %s | %s\n", now, tag, msg)
}// Sleep 模拟业务耗时
func Sleep(min, max float64) {delta := max - mins := min + rand.Float64()*deltatime.Sleep(time.Duration(s*1000) * time.Millisecond)
}// RandString 生成8位ID
func RandString() string {chars := "0123456789abcdef"res := make([]byte, 8)for i := 0; i < 8; i++ {res[i] = chars[rand.Intn(len(chars))]}return string(res)
}// RandomChoice 随机选择
func RandomChoice(list []string) string {return list[rand.Intn(len(list))]
}/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Producer Consumer  Pattern 生产者消费者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 19:32
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : jewelry.go
*/
package models// 数据模型 实体
type JewelryStage stringconst (Raw       JewelryStage = "原料"Processed JewelryStage = "成品"Qualified JewelryStage = "已分级"Salable   JewelryStage = "可销售"
)type Jewelry struct {ID           stringMaterial     stringStage        JewelryStageQualityLevel string
}/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Producer Consumer  Pattern 生产者消费者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 19:31
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : manager.go
*/
package coreimport ("godesginpattern/producerconsumer/models""sync"
)// 核心队列 & 停止管理器
// QueueManager 全局队列单例
type QueueManager struct {RawQueue     chan *models.JewelryProcessQueue chan *models.JewelryQualityQueue chan *models.JewelrySaleQueue    chan *models.JewelryStopChan      chan struct{}ProducedCount intMutex         sync.Mutex
}var instance *QueueManager
var once sync.Once// GetInstance 单例模式
func GetInstance() *QueueManager {once.Do(func() {instance = &QueueManager{RawQueue:     make(chan *models.Jewelry, 5),ProcessQueue: make(chan *models.Jewelry, 5),QualityQueue: make(chan *models.Jewelry, 5),SaleQueue:    make(chan *models.Jewelry, 5),StopChan:     make(chan struct{}),}})return instance
}// IsStopped 判断是否停止
func (m *QueueManager) IsStopped() bool {select {case <-m.StopChan:return truedefault:return false}
}// Stop 发送停止信号
func (m *QueueManager) Stop() {close(m.StopChan)
}// IncProducedCount 线程安全计数
func (m *QueueManager) IncProducedCount() int {m.Mutex.Lock()defer m.Mutex.Unlock()m.ProducedCount++return m.ProducedCount
}/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Producer Consumer  Pattern 生产者消费者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 19:32
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : producer.go
*/
package serviceimport ("fmt""godesginpattern/producerconsumer/config""godesginpattern/producerconsumer/core""godesginpattern/producerconsumer/models""godesginpattern/producerconsumer/utils"
)// 原料生产者
func RawMaterialProducer() {mgr := core.GetInstance()for !mgr.IsStopped() {utils.Sleep(config.TimeRaw, config.TimeRawMax)mat := utils.RandomChoice(config.RawMaterials)j := &models.Jewelry{ID:       utils.RandString(),Material: mat,Stage:    models.Raw,}select {case mgr.RawQueue <- j:cnt := mgr.IncProducedCount()utils.Info("ProducerService",fmt.Sprintf("原料采购完成 | [原料]%s | 队列剩余: %d | 已生产:%d/%d",mat, len(mgr.RawQueue), cnt, config.MaxProduceCount))if cnt >= config.MaxProduceCount {utils.Info("ProducerService", "已达到最大生产数量,准备停止生产")mgr.Stop()return}case <-mgr.StopChan:return}}
}/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Producer Consumer  Pattern 生产者消费者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 19:32
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : consumer.go
*/
package serviceimport ("fmt""godesginpattern/producerconsumer/config""godesginpattern/producerconsumer/core""godesginpattern/producerconsumer/models""godesginpattern/producerconsumer/utils"
)// 全流程消费者(加工 / 质检 / 仓储 / 销售)
// ProcessConsumer 加工
func ProcessConsumer() {mgr := core.GetInstance()for {select {case j := <-mgr.RawQueue:utils.Sleep(config.TimeProcess, config.TimeProcessMax)utils.Info("ConsumerService", fmt.Sprintf("开始加工 | [%s]%s", j.Stage, j.Material))j.Stage = models.Processedmgr.ProcessQueue <- jutils.Info("ConsumerService",fmt.Sprintf("加工完成 | [成品]%s | 队列剩余: %d", j.Material, len(mgr.ProcessQueue)))case <-mgr.StopChan:if len(mgr.RawQueue) == 0 {return}}}
}// QualityConsumer 质检
func QualityConsumer() {mgr := core.GetInstance()for {select {case j := <-mgr.ProcessQueue:utils.Sleep(config.TimeQuality, config.TimeQualityMax)utils.Info("ConsumerService", fmt.Sprintf("开始质检 | [%s]%s", j.Stage, j.Material))j.QualityLevel = utils.RandomChoice(config.QualityLevels)j.Stage = models.Qualifiedmgr.QualityQueue <- jutils.Info("ConsumerService",fmt.Sprintf("质检完成 | %s%s | 队列剩余: %d", j.QualityLevel, j.Material, len(mgr.QualityQueue)))case <-mgr.StopChan:if len(mgr.ProcessQueue) == 0 {return}}}
}// WarehouseConsumer 仓储
func WarehouseConsumer() {mgr := core.GetInstance()for {select {case j := <-mgr.QualityQueue:utils.Sleep(config.TimeWarehouse, config.TimeWarehouseMax)utils.Info("ConsumerService", fmt.Sprintf("开始入库 | [%s]%s%s", j.Stage, j.QualityLevel, j.Material))j.Stage = models.Salablemgr.SaleQueue <- jutils.Info("ConsumerService",fmt.Sprintf("入库完成 | %s%s(已入库可销售) | 队列剩余: %d", j.QualityLevel, j.Material, len(mgr.SaleQueue)))case <-mgr.StopChan:if len(mgr.QualityQueue) == 0 {return}}}
}// SaleConsumer 销售
func SaleConsumer() {mgr := core.GetInstance()for {select {case j := <-mgr.SaleQueue:utils.Sleep(config.TimeSale, config.TimeSaleMax)utils.Info("ConsumerService",fmt.Sprintf("开始销售 | [可销售]%s%s(已入库可销售)", j.QualityLevel, j.Material))utils.Info("ConsumerService",fmt.Sprintf("销售成功 | %s%s(已入库可销售)\n", j.QualityLevel, j.Material))case <-mgr.StopChan:if len(mgr.SaleQueue) == 0 {return}}}
}

  

调用:

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 19:46
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : producerconsumerbll.go
*/
package bllimport ("fmt""godesginpattern/producerconsumer/config""godesginpattern/producerconsumer/core""godesginpattern/producerconsumer/service""godesginpattern/producerconsumer/utils""os""os/signal""sync""syscall"
)// 启动所有 Goroutine
func ProducerConsumerMain() {utils.Info("Main", "============================================================")utils.Info("Main", "珠宝全流程生产销售系统(企业级生产者消费者模式)")utils.Info("Main", fmt.Sprintf("最大生产数量限制:%d", config.MaxProduceCount))utils.Info("Main", "============================================================")mgr := core.GetInstance()var wg sync.WaitGroup// 启动生产者for i := 0; i < config.ProducerThreads; i++ {wg.Add(1)go func() {defer wg.Done()service.RawMaterialProducer()}()}// 启动消费者for i := 0; i < config.ProcessThreads; i++ {wg.Add(1)go func() {defer wg.Done()service.ProcessConsumer()}()}for i := 0; i < config.QualityThreads; i++ {wg.Add(1)go func() {defer wg.Done()service.QualityConsumer()}()}for i := 0; i < config.WarehouseThreads; i++ {wg.Add(1)go func() {defer wg.Done()service.WarehouseConsumer()}()}for i := 0; i < config.SaleThreads; i++ {wg.Add(1)go func() {defer wg.Done()service.SaleConsumer()}()}// 监听 Ctrl+CsigChan := make(chan os.Signal, 1)signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)go func() {<-sigChanutils.Info("Main", "检测到 Ctrl+C,触发优雅停止...")mgr.Stop()}()// 等待所有协程完成wg.Wait()utils.Info("Main", "所有业务线程已正常退出")utils.Info("Main", "系统正常结束,输出停止")
}

  

输出:

image

 

http://www.jsqmd.com/news/1044330/

相关文章:

  • 普宁哪家家具又好又便宜|质量过硬价格透明哪家店 - 品牌观察
  • AWS 删除用户的权限会发生什么
  • 高温冶炼车间炉前工位工业平板采购方案,避开高温死机故障
  • 普宁家具店推荐|展厅大款式新去哪家逛 - 品牌观察
  • 【电赛/毕设降维打击】别让 STM32 跑视觉了!树莓派/香橙派 Linux 边缘计算、NPU 加速与双核异构架构硬核避坑指南前言
  • 3步打造专业级Vue日历应用:dayspan-vuetify完整指南
  • 寄快递省钱攻略:2026快递品牌性价比与折扣全对比 - 快递物流资讯
  • 2026 泰州防水补漏靠谱服务商盘点:屋面 / 厨卫 / 外墙 / 地下室渗水维修详解,适配苏中滨江梅雨低洼防水甄选指南 - 宅安选房屋修缮
  • 学习总结8
  • 广东省佛山市南海区吃川菜推荐去哪家?实测 4 家正宗川味馆子 - 速递信息
  • 批量合成视频工具 批量剪辑视频神器免费版 一键生成 青柠剪吧助手全能版
  • MC68060 JTAG边界扫描技术详解:从原理到硬件调试实战
  • MC9S12XE Flash模块深度解析:内存映射、寄存器配置与安全机制实战
  • 计算机教材策划与写作:如何将AI与云计算前沿知识结构化
  • 终极指南:使用OpenCore Legacy Patcher免费升级老旧Mac到最新macOS系统
  • 无锡仿真植物造景布置怎么选?2026软装市场现状与服务商选型报告 - 三棵树园艺
  • 别再盲目手写论文!这7款AI工具一键生成,全学科秒出稿! - 麟书学长
  • 2026 芜湖防水补漏靠谱服务商盘点:屋面 / 厨卫 / 外墙 / 地下室渗水维修详解,适配皖南滨江梅雨潮湿防水甄选指南 - 宅安选房屋修缮
  • 学习总结9
  • Elsevier Tracker:告别投稿焦虑,3分钟实现学术审稿状态实时可视化
  • MC9S08JM60 ADC误差分析与IIC协议精解:提升嵌入式测量与通信稳定性
  • 如何快速构建抖音直播数据采集系统:完整实战指南
  • GPT-4.1是假消息?揭穿大模型命名乱象与Turbo真实能力
  • 端午不打烊!27 届成都锦城菁英单招校区正常开放,可预约全天访校 - 成都单招培训
  • Moteus:当开源精神遇见高性能无刷伺服控制
  • 2026降AIGC技术白皮书:实测验证工具榜与精准选型导航
  • SparkCat恶意软件深度解析:移动安全攻防实战与防护指南
  • 2026年6月卧式潜水泵厂家推荐 - 多才菠萝
  • 2026海口名表回收行情解析!哪些款式保值抗跌?避坑指南速看 - 奢品小当家
  • 深入解析ColdFire EIM总线时序:从基础读写到突发传输实战