golang worker channel 模式
- 大概流程就是job -> JobQueue
- 调度器循环获取JobQueue ,获取到的job ,再去异步获取等待可用的 worker,取出 chan Job,将job 写入改worker的 chan Job
- worker 处理任务,先处理 case job := <-w.JobChannel: 处理完成后再将 chan Job 写入到worker 里面,等待调度去取调用
package mainimport ("log""os""strconv""sync""time"
)var (MaxWorker intMaxQueue intJobQueue chan Job
)func init() {var err errorMaxWorker, err = strconv.Atoi(os.Getenv("MAX_WORKERS"))if err != nil {MaxWorker = 5 // 默认值}MaxQueue, err = strconv.Atoi(os.Getenv("MAX_QUEUE"))if err != nil {MaxQueue = 10 // 默认值}JobQueue = make(chan Job, MaxQueue)
}type Payload struct {// Payload的属性
}func (p *Payload) UploadToS3() error {// 模拟上传操作log.Println("Uploading to S3")return nil
}type Job struct {Payload Payload
}type Worker struct {WorkerPool chan chan JobJobChannel chan Jobquit chan bool
}func NewWorker(workerPool chan chan Job) Worker {return Worker{WorkerPool: workerPool,JobChannel: make(chan Job),quit: make(chan bool)}
}func (w Worker) Start() {go func() {for {w.WorkerPool <- w.JobChannelselect {case job := <-w.JobChannel:if err := job.Payload.UploadToS3(); err != nil {log.Printf("Error uploading to S3: %s", err)}case <-w.quit:return}}}()
}func (w *Worker) Stop() {go func() {w.quit <- true // 通知工作线程停止}()
}type Dispatcher struct {WorkerPool chan chan JobmaxWorkers intworkers []Worker // 新增:用于跟踪所有工作线程quit chan bool // 用于停止dispatch循环
}func NewDispatcher(maxWorkers int) *Dispatcher {return &Dispatcher{WorkerPool: make(chan chan Job, maxWorkers),maxWorkers: maxWorkers,workers: make([]Worker, 0, maxWorkers),}
}func (d *Dispatcher) Runs() {for i := 0; i < d.maxWorkers; i++ {worker := NewWorker(d.WorkerPool)d.workers = append(d.workers, worker) // 跟踪新创建的工作线程worker.Start()}go d.dispatch()
}func (d *Dispatcher) dispatch() {for {select {// 从JobQueue中获取一个jobcase job := <-JobQueue:go func(job Job) {// 尝试获取一个可用的worker job channel,阻塞直到有可用的workerjobChannel := <-d.WorkerPool// 分发job到worker job channel中jobChannel <- job}(job)case <-d.quit:// 退出return}}
}func (d *Dispatcher) StopAllWorkers() {var wg sync.WaitGroupfor _, worker := range d.workers {wg.Add(1)go func(w Worker) {w.Stop() // 停止工作线程wg.Done()}(worker)}wg.Wait() // 等待所有工作线程安全退出
}func (d *Dispatcher) Stop() {d.quit <- trued.StopAllWorkers()
}func main() {dispatcher := NewDispatcher(MaxWorker)dispatcher.Runs()// 模拟作业提交for i := 0; i < 20; i++ {payload := Payload{ /* ... */ }job := Job{Payload: payload}JobQueue <- job}// 等待一段时间,以便可以看到工作的完成time.Sleep(10 * time.Second)
}相关文章:
golang worker channel 模式
大概流程就是job -> JobQueue调度器循环获取JobQueue ,获取到的job ,再去异步获取等待可用的 worker,取出 chan Job,将job 写入改worker的 chan Jobworker 处理任务,先处理 case job : <-w.JobChannel: 处理完成后再将 chan…...
舔狗日记之好一条舔狗
闲来没事,爬了下vx《舔狗日记》,感觉挺有意思的,分享出来给大家看看。 PS:仅供娱乐,侵删。 舔狗2023 舔狗日记 2023年10月11日 晴天 你们根本不懂舔狗的快乐。被舔的人,无法预知接下来会不会继续被舔&…...
【地理位置识别】IP归属地应用的特点
IP归属地应用是一类用于确定特定IP地址的地理位置信息(通常是城市、地区或国家)的工具和服务。以下是IP归属地应用的几个主要特点: 地理位置识别: IP归属地应用主要用于确定IP地址的地理位置。这可以帮助组织更好地了解其网站访问…...
华为实验基础(2):路由器基础
一、路由器的分类 1、从功能、性能和应用方面划分: (1) 骨干路由器 :骨干路由器是实现主干网络互连的关键设备,通常采用模块化结构,通过热备 份、双电源和双数据通路等冗余技术提高可靠性 ,华…...
婚姻管理系统-使用bbst数据结构
使用到希尔排序和归并排序,文件存储 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> #include <string.h> //名字的最大长度 #define NameMax 30 //全局的文件指针变量 FILE* file, * file_admin, * file_divorce; /…...
软件架构的概念
1.软件架构演化 为了适应用户的新需求、业务环境和运行环境的变化等,软件架构需要不断地进行自身的演化,也就是说软件架构的演化就是为了维持软件架构自身的有用性。 本质上讲,软件架构的演化就是软件整体结构的演化,演化过程涵盖…...
kubernetes存储-secrets
一、从文件创建 二、编写yaml文件 三、将Secret挂载到Volume中 四、向指定路径映射 secret 密钥 五、将Secret设置为环境变量 六、存储docker registry的认证信息...
Springboot使用EasyExcel导入导出Excel文件
1,准备Excel文件和数据库表结果 2,导入代码 1,引入依赖 <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifac…...
Pytorch L1,L2正则化
L1正则化和L2正则化是常用的正则化技术,用于在机器学习模型中控制过拟合。它们的主要区别在于正则化项的形式和对模型参数的影响。 L1正则化(Lasso正则化): 正则化项形式:L1正则化使用模型参数的绝对值之和作为正则化…...
【Elasticsearch 未授权访问漏洞复现】
文章目录 一、漏洞描述二、漏洞复现三、修复建议 一、漏洞描述 ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布&am…...
pytorch笔记:PackedSequence对象送入RNN
pytorch 笔记:PAD_PACKED_SEQUENCE 和PACK_PADDED_SEQUENCE-CSDN博客 当使用pack_padded_sequence得到一个PackedSequence对象并将其送入RNN(如LSTM或GRU)时,RNN内部会进行特定的操作来处理这种特殊的输入形式。 使用PackedSequ…...
C#WPF工具提示(ToolTip)实例
本文演示C#WPF工具提示(ToolTip)实例 ToolTip ToolTip是当鼠标移到某个控件上后可以弹出提示的控件 属性说明 1、HasDropShadow 决定工具提示是否具有扩散的黑色阴影,使其和背后的窗口区别开来 2、Placement 使用PlacementMode枚举值决定如何放置工具提示。默认值是M…...
智慧矿山系统中的猴车安全监测与识别
智慧矿山是近年来兴起的一种采用人工智能(AI)技术的矿山管理方式,它通过利用智能传感设备和先进算法来实现对矿山环境和设备进行监测和管理,从而提高矿山的安全性和效率。在智慧矿山的AI算法系列中,猴车不安全行为识别…...
网络协议--TCP连接的建立与终止
18.1 引言 TCP是一个面向连接的协议。无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。本章将详细讨论一个TCP连接是如何建立的以及通信结束后是如何终止的。 这种两端间连接的建立与无连接协议如UDP不同。我们在第11章看到一端使用UDP向另一端发…...
react条件渲染
目录 前言 1. 使用if语句 2. 使用三元表达式 3. 使用逻辑与操作符 列表渲染 最佳实践和注意事项 1. 使用合适的条件判断 2. 提取重复的逻辑 3. 使用适当的key属性 总结 前言 在React中,条件渲染指的是根据某个条件来决定是否渲染特定的组件或元素。这在构…...
Docker中Failed to initialize NVML: Unknown Error
参考资料 Docker 中无法使用 GPU 时该怎么办(无法初始化 NVML:未知错误) SOLVED Docker with GPU: “Failed to initialize NVML: Unknown Error” 解决方案需要的条件: 需要在服务器上docker的admin list之中. 不需要服务器整体的admin权限.…...
学习笔记|单样本秩和检验|假设检验摘要|Wilcoxon符号检验|规范表达|《小白爱上SPSS》课程:SPSS第十一讲 | 单样本秩和检验如何做?很轻松!
目录 学习目的软件版本原始文档单样本秩和检验一、实战案例二、统计策略三、SPSS操作1、正态性检验2.单样本秩和检验 四、结果解读第一,假设检验摘要第二,Wilcoxon符号检验结果摘要。第三,Wilcoxon符号秩检验图第四,数…...
ttkefu在线客服在客户联络领域的价值
随着互联网的快速发展,越来越多的企业开始注重在线客服的应用。ttkefu作为一款智能在线客服系统,在客户联络领域中展现出了巨大的价值。本文将详细介绍ttkefu在线客服在客户联络领域的应用优势、专家分析以及未来发展趋势。 一、ttkefu在线客服简介 tt…...
创新方案|2023如何用5种新形式重塑疫后实体门店体验
在电商盛行的当下,线上购物已成为新零售的重要组成部分,实体零售业正处于两难境地。一方面,实体零售是绝对有必要的:美国约 85% 的销售额来自实体商店。 另一方面,尽管增长放缓,但电商收入占销售总额的比例…...
Aqua Data Studio 2023.1
为什么选择 Aqua Data Studio? 随着数据在业务中的作用不断发展,组织需要一种有效的方法来简化复杂的技术任务并缩小 IT 和业务团队之间的差距。 使用多个数据库平台不再复杂。使用 Aqua Data Studio 简化您的所有数据管理流程和任务:这是一…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
