使用golang编写一个并发工作队列
作者:u010278923 发布时间:2023-09-02 20:54:08
标签:golang,并发,队列
其实golang用一个函数可以构建一个并发队列,现在编写一个灵活可控的队列程序
先定义一个工作
type Worker struct {
ID int
RepJobs chan int64
SM *SM
quit chan bool
}
包含了workid和执行任务的id,上面的SM只是任务具体内容,这个和具体业务相关,大家自己编写自己的SM业务逻辑
然后定义工作池
type workerPool struct {
workerChan chan *Worker
workerList []*Worker
}
这个里面定义了一个工作队列的切片,可以自定义工作队列的个数,甚至后期还可以添加work,还定义了一个队列类型的管道。
定义完成过后就可以初始化工作池了
func InitWorkerPool() error {
n := 3
WorkerPool = &workerPool{
workerChan: make(chan *Worker, n),
workerList: make([]*Worker, 0, n),
}
for i := 0; i < n; i++ {
worker := NewWorker(i)
WorkerPool.workerList = append(WorkerPool.workerList, worker)
worker.Start()
log.Debugf("worker %d started", worker.ID)
}
return nil
}
这个里面我写死了worker的个数是3,当然这个可以通过读取配置文件或者参数传递的方式;这个里面逐一启动work
worker.Start(),这个是关键
func (w *Worker) Start() {
go func() {
for {
WorkerPool.workerChan <- w
select {
case jobID := <-w.RepJobs:
log.Debugf("worker: %d, will handle job: %d", w.ID, jobID)
w.handleRepJob(jobID)
case q := <-w.quit:
if q {
log.Debugf("worker: %d, will stop.", w.ID)
return
}
}
}
}()
}
这个就是go 启动一个协程,先把自己放到workerChan中,然后不断从w.RepJobs管道中获取任务并执行,如果执行完成后又把自己放回到队列中。
所以如果你要有任务需要执行,放到这个管道中即可
func Dispatch() {
for {
select {
case job := <-jobQueue:
go func(jobID int64) {
println("Trying to dispatch job: %d", jobID)
worker := <-WorkerPool.workerChan
worker.RepJobs <- jobID
}(job)
}
}
}
从管道中拿出一个worker并把任务id放到worker中去执行。
当然你可以停止worker,甚至可以停止job
func (w *Worker) Stop() {
go func() {
w.quit <- true
}()
}
func (wp *workerPool) StopJobs(jobs []int64) {
log.Debugf("Works working on jobs: %v will be stopped", jobs)
for _, id := range jobs {
for _, w := range wp.workerList {
if w.SM.JobID == id {
log.Debugf("found a worker whose job ID is %d, will try to stop it", id)
w.SM.Stop(id)
}
}
}
}
补充一下,int64和字符串转换。
string到int
int,err:=strconv.Atoi(string)
string到int64
int64, err := strconv.ParseInt(string, 10, 64)
int到string
string:=strconv.Itoa(int)
int64到string
string:=strconv.FormatInt(int64,10)
以上为个人经验,希望能给大家一个参考
来源:https://chenxy.blog.csdn.net/article/details/72582200
0
投稿
猜你喜欢
- 五花八门的SQL产品多得要命,或许你早顾不得其它甩开袖子就动手干了。但你要同时采用ASP和SQL的话就可能会头晕。MySQL、SQL Ser
- 在数据库开发过程中,当你检索的数据只是一条记录时,你所编写的事务语句代码往往使用SELECT INSERT 语句。但是我们常常会遇到这样情况
- 一、设计说明设计这个自动化的目的是想要交替、重复地使用固定的几个分区(分区编号01~05)来保存数据,当最后一个分区就是快满的时候,我们会把
- 先上个效果图,就是用左右尖括号可改变中间日期的值。(点击中间显示区域有时间选择器弹框,用的插件就不说了,主要说自己原创的部分) &
- 1、简单的按钮js事件 用于判断和显示提示 <script type="text/javascript&
- 为了顺利的开发一个多语言的国际化J2EE程序,需要修改数据库字符集,我的做法如下:安装 MySq时选择字符集为UTF-8修改MySql安装目
- 1.首先,我们需要过滤所有客户端提交的内容,其中包括?id=N一类,另外还有提交的html代码中的操作数据库的select及asp文件操作语
- 用Dreamweaver制作网页时,如果插入的图片、GIF动画、声音、视频或链接的网页是用中文命名的,在用IE浏览器浏览时可能显示不出来。以
- 核心代码# -*- coding: utf-8 -*-'''python读取英文文件,将每个单词按照空格分开,并将每
- 前几天要写一个东西里面有用到读文件的。 可是我不想用FSO,我怕有的空间不支持。 &nbs
- 百度有啊2009年情人节logo——大纸袋GG给大纸袋MM送了枝玫瑰花,大纸袋MM奖励了大纸袋GG一个吻,好可爱!淘宝网2009年情人节lo
- 判断服务器是否安装了某种asp组件,比较常用的代码如下:代码如下:<% '功能:检查是否存在系统组件或组件是否安装成功
- 前言使用 Pandas 的between 、cut、qcut 和 value_count离散化数值变量。分箱是一种常见的数据预处理技术有时也
- blankzheng的blog:http://www.planabc.net/经常有朋友问我,网站要在哪些浏览器上测试?要达到怎样的兼容?我
- 鉴于人手严重不足(当时算两个半人的资源),打消了逐个库手动去改的念头。当前的程序结构不允许搞革命的做法,只能搞搞改良,所以准备搞个自动化工具
- 谈到“登录”,大多数人脑海中会立刻浮现出那个“两小框:一用户名,一密码,外加一按钮”的经典豆腐块, 这样的功能模块在互联网上屡见不鲜, 成为
- 写好脚本,注册好服务之后,经测试,ORACLE可以随RHEL启动而启动,但不能随系统关闭而关闭。在网上找答案,发现几乎所有的设置过程帖子都是
- Instr函数与InstrRev函数大家都应该很熟悉,但是如果你看过《ASP * 站开发实践教程》,你应该注意一下。该书中介绍它们时是很有迷
- 今天有朋友问到如下一则案例,ORA-01114,ORA-27067以及OSD-04026错误同时出现:*** ACTION NAME:()
- 只是做笔记,没什么!! 代码如下:--创建测试表 CREATE TABLE [dbo].[Student]( [ID] [int