使用golang编写一个并发工作队列


Posted in Golang onMay 08, 2021

其实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)

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。如有错误或未考虑完全的地方,望不吝赐教。

Golang 相关文章推荐
go语言中切片与内存复制 memcpy 的实现操作
Apr 27 Golang
Golang 实现超大文件读取的两种方法
Apr 27 Golang
解决Golang中ResponseWriter的一个坑
Apr 27 Golang
基于Go Int转string几种方式性能测试
Apr 28 Golang
Go语言 go程释放操作(退出/销毁)
Apr 30 Golang
go类型转换及与C的类型转换方式
May 05 Golang
golang switch语句的灵活写法介绍
May 06 Golang
Golang生成Excel文档的方法步骤
Jun 09 Golang
go开发alertmanger实现钉钉报警
Jul 16 Golang
golang定时器
Apr 14 Golang
Golang 对es的操作实例
Apr 20 Golang
Golang ort 中的sortInts 方法
Apr 24 Golang
Go 在 MongoDB 中常用查询与修改的操作
May 07 #Golang
golang 实现时间戳和时间的转化
May 07 #Golang
Golang Gob编码(gob包的使用详解)
May 07 #Golang
go mod 安装依赖 unkown revision问题的解决方案
解决golang 关于全局变量的坑
May 06 #Golang
Goland使用Go Modules创建/管理项目的操作
解决goland 导入项目后import里的包报红问题
You might like
php获取英文姓名首字母的方法
2015/07/13 PHP
PHP的Yii框架使用中的一些错误解决方法与建议
2015/08/21 PHP
PHP中如何判断exec函数执行成功?
2016/08/04 PHP
PHP 根据key 给二维数组分组
2016/12/09 PHP
php 截取GBK文档某个位置开始的n个字符方法
2017/03/08 PHP
使用swoole 定时器变更超时未支付订单状态的解决方案
2019/07/24 PHP
浅谈laravel-admin form中的数据,在提交后,保存前,获取并进行编辑
2019/10/21 PHP
Jquery的hide及toggle方法让超链接慢慢消失
2013/09/06 Javascript
js实现鼠标悬停图片上时滚动文字说明的方法
2015/02/17 Javascript
BootStrap入门教程(二)之固定的内置样式
2016/09/19 Javascript
es6学习笔记之Async函数基本教程
2017/05/11 Javascript
Vue路由跳转问题记录详解
2017/06/15 Javascript
vue-resouce设置请求头的三种方法
2017/09/12 Javascript
Vee-validate 父组件获取子组件表单校验结果的实例代码
2019/05/20 Javascript
为vue项目自动设置请求状态的配置方法
2019/06/09 Javascript
vue项目打包为APP,静态资源正常显示,但API请求不到数据的操作
2020/09/12 Javascript
详解VUE中的插值( Interpolation)语法
2020/10/18 Javascript
Js利用正则表达式去除字符串的中括号
2020/11/23 Javascript
python sqlobject(mysql)中文乱码解决方法
2008/11/14 Python
kNN算法python实现和简单数字识别的方法
2014/11/18 Python
Cpy和Python的效率对比
2015/03/20 Python
Python使用回溯法子集树模板解决爬楼梯问题示例
2017/09/08 Python
利用arcgis的python读取要素的X,Y方法
2018/12/22 Python
在Python 中实现图片加框和加字的方法
2019/01/26 Python
python绘制漏斗图步骤详解
2019/03/04 Python
python批量创建指定名称的文件夹
2019/03/21 Python
Python OpenCV实现视频分帧
2019/06/01 Python
Python3分析处理声音数据的例子
2019/08/27 Python
解决json中ensure_ascii=False的问题
2020/04/03 Python
举例讲解Python装饰器
2020/12/24 Python
Roxy俄罗斯官方网站:冲浪和滑雪板的一切
2020/06/20 全球购物
大一自我鉴定范文
2013/10/04 职场文书
实习护士自荐信
2014/06/21 职场文书
群众路线表态发言材料
2014/10/17 职场文书
部门经理迟到检讨书
2015/02/16 职场文书
离婚案件上诉状
2015/05/23 职场文书