使用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 相关文章推荐
Golang 正则匹配效率详解
Apr 25 Golang
Go 实现英尺和米的简单单位换算方式
Apr 29 Golang
对Golang中的FORM相关字段理解
May 02 Golang
golang中的并发和并行
May 08 Golang
golang中字符串MD5生成方式总结
Jul 04 Golang
Go语言应该什么情况使用指针
Jul 25 Golang
golang实现一个简单的websocket聊天室功能
Oct 05 Golang
Go 语言中 20 个占位符的整理
Oct 16 Golang
Go语言基础函数基本用法及示例详解
Nov 17 Golang
简单聊聊Golang中defer预计算参数
Mar 25 Golang
Go获取两个时区的时间差
Apr 20 Golang
Golang入门之计时器
May 04 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
农民C键的运用技巧
2020/03/04 星际争霸
PHP判断远程url是否有效的几种方法小结
2011/10/08 PHP
Yii 框架使用Forms操作详解
2020/05/18 PHP
Javascript 面向对象编程(一) 封装
2011/08/28 Javascript
浅谈Javascript鼠标和滚轮事件
2012/06/27 Javascript
js确认删除对话框效果的示例代码
2014/02/20 Javascript
JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)
2014/08/16 Javascript
jquery中JSON的解析方式
2015/03/16 Javascript
jquery自定义表格样式
2015/11/23 Javascript
jQuery 3.0十大新特性
2016/07/06 Javascript
JavaScript如何实现跨域请求
2016/08/05 Javascript
jQuery根据ID、CLASS、等获取对象的实例
2016/12/04 Javascript
微信分享调用jssdk实例
2017/06/08 Javascript
JS实现带动画的回到顶部效果
2017/12/28 Javascript
在react-router4中进行代码拆分的方法(基于webpack)
2018/03/08 Javascript
微信小程序自定义tab实现多层tab嵌套功能
2018/06/15 Javascript
JQuery样式操作、click事件以及索引值-选项卡应用示例
2019/05/14 jQuery
JavaScript实现随机点名器
2020/03/25 Javascript
Python中不同进制互相转换(二进制、八进制、十进制和十六进制)
2015/04/05 Python
python杀死一个线程的方法
2015/09/06 Python
python实现简单http服务器功能
2018/09/17 Python
Python数据可视化库seaborn的使用总结
2019/01/15 Python
10分钟用python搭建一个超好用的CMDB系统
2019/07/17 Python
python numpy生成等差数列、等比数列的实例
2020/02/25 Python
tensorflow从ckpt和从.pb文件读取变量的值方式
2020/05/26 Python
html5通过postMessage进行跨域通信的方法
2017/12/04 HTML / CSS
高校自主招生自荐信
2013/12/09 职场文书
给老师的道歉信
2014/01/11 职场文书
如何编写优秀的食品项目创业计划书
2014/01/23 职场文书
镇班子对照检查材料思想汇报
2014/09/24 职场文书
2014年采购工作总结
2014/11/20 职场文书
2015年度内部审计工作总结
2015/05/20 职场文书
音乐剧猫观后感
2015/06/04 职场文书
教师研修随笔感言
2015/11/18 职场文书
2016重阳节红领巾广播稿
2015/12/18 职场文书
【海涛dota】偶遇拉娜娅 质量局德鲁伊第一视角解说
2022/04/01 DOTA