使用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
golang json数组拼接的实例
Apr 28 Golang
golang DNS服务器的简单实现操作
Apr 30 Golang
golang 定时任务方面time.Sleep和time.Tick的优劣对比分析
May 05 Golang
Golang之sync.Pool使用详解
May 06 Golang
golang 实现并发求和
May 08 Golang
Golang全局变量加锁的问题解决
May 08 Golang
浅谈Golang 切片(slice)扩容机制的原理
Jun 09 Golang
深入理解go slice结构
Sep 15 Golang
Golang中channel的原理解读(推荐)
Oct 16 Golang
Go语言grpc和protobuf
Apr 13 Golang
GoFrame基于性能测试得知grpool使用场景
Jun 21 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绘图中显示不出图片的原因及解决
2014/03/05 PHP
php通过文件头判断格式的方法
2016/05/28 PHP
在Yii2特定页面如何禁用调试工具栏Debug Toolbar详解
2017/08/07 PHP
PHP变量的作用范围实例讲解
2020/12/22 PHP
javascript+dom树型菜单类,希望朋友们一起进步
2007/05/03 Javascript
css值转换成数值请抛弃parseInt
2011/10/24 Javascript
返回上一页并自动刷新的JavaScript代码
2014/02/19 Javascript
jQuery使用元素属性attr赋值详解
2015/02/27 Javascript
js获取微信版本号的方法
2015/05/12 Javascript
纯javascript判断查询日期是否为有效日期
2015/08/24 Javascript
js重写方法的简单实现
2016/07/10 Javascript
实例讲解JavaScript中call、apply、bind方法的异同
2016/09/13 Javascript
vue中改变选中当前项的显示隐藏或者状态的实现方法
2018/02/08 Javascript
node基于puppeteer模拟登录抓取页面的实现
2018/05/09 Javascript
Openlayers实现地图的基本操作
2020/09/28 Javascript
WebPack工具运行原理及入门教程
2020/12/02 Javascript
python 实现上传图片并预览的3种方法(推荐)
2017/07/14 Python
TensorFlow模型保存/载入的两种方法
2018/03/08 Python
Python中循环引用(import)失败的解决方法
2018/04/22 Python
对python中两种列表元素去重函数性能的比较方法
2018/06/29 Python
详谈Python 窗体(tkinter)表格数据(Treeview)
2018/10/11 Python
nohup后台启动Python脚本,log不刷新的解决方法
2019/01/14 Python
PyTorch中topk函数的用法详解
2020/01/02 Python
Python Opencv中用compareHist函数进行直方图比较对比图片
2020/04/07 Python
django表单中的按钮获取数据的实例分析
2020/07/31 Python
台湾母婴用品购物网站:Infant婴之房
2018/06/15 全球购物
可靠的数据流传输TCP
2016/03/15 面试题
财务会计专业毕业生自荐信
2013/10/02 职场文书
网上签名寄语活动留言
2014/01/18 职场文书
数学教学随笔感言
2014/02/17 职场文书
运动会宣传口号
2014/06/09 职场文书
2015年禁毒宣传活动总结
2015/03/25 职场文书
2016年9月份红领巾广播稿
2015/12/21 职场文书
大学生就业指导课心得体会
2016/01/15 职场文书
高一作文之暖冬
2019/11/09 职场文书
MySQL高级进阶sql语句总结大全
2022/03/16 MySQL