使用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 Int转string几种方式性能测试
Apr 28 Golang
解决Golang中goroutine执行速度的问题
May 02 Golang
解决goland 导入项目后import里的包报红问题
May 06 Golang
go语言基础 seek光标位置os包的使用
May 09 Golang
golang 实用库gotable的具体使用
Jul 01 Golang
Go 语言结构实例分析
Jul 04 Golang
go开发alertmanger实现钉钉报警
Jul 16 Golang
浅谈GO中的Channel以及死锁的造成
Mar 18 Golang
Go归并排序算法的实现方法
Apr 06 Golang
Go语言安装并操作redis的go-redis库
Apr 14 Golang
Golang ort 中的sortInts 方法
Apr 24 Golang
Go中使用gjson来操作JSON数据的实现
Aug 14 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
mysql5的sql文件导入到mysql4的方法
2008/10/19 PHP
Zend Framework框架中实现Ajax的方法示例
2017/06/27 PHP
Ajax,UTF-8还是GB2312 eval 还是execScript
2008/11/13 Javascript
(function($){...})(jQuery)的意思
2010/07/22 Javascript
深入理解JavaScript系列(14) 作用域链介绍(Scope Chain)
2012/04/12 Javascript
jquery 插件学习(六)
2012/08/06 Javascript
js中eval()函数和trim()去掉字符串左右空格应用
2013/02/02 Javascript
button没写type=button会导致点击时提交
2014/03/06 Javascript
js实现类似新浪微博首页内容渐显效果的方法
2015/04/10 Javascript
js+CSS实现模拟华丽的select控件下拉菜单效果
2015/09/01 Javascript
jQuery封装的屏幕居中提示信息代码
2016/06/08 Javascript
JavaScript从0开始构思表情插件
2016/07/26 Javascript
Angularjs中ng-repeat-start与ng-repeat-end的用法实例介绍
2016/12/31 Javascript
bootstrap table 多选框分页保留示例代码
2017/03/08 Javascript
vue拦截器Vue.http.interceptors.push使用详解
2017/04/22 Javascript
react中使用css的7中方式(最全总结)
2019/02/11 Javascript
使用vue-router切换页面时,获取上一页url以及当前页面url的方法
2019/05/06 Javascript
移动端吸顶fixbar的解决方案详解
2019/07/17 Javascript
小程序中的箭头函数的具体使用
2020/06/19 Javascript
浅谈vue中使用编辑器vue-quill-editor踩过的坑
2020/08/03 Javascript
Python入门篇之文件
2014/10/20 Python
Python中使用dom模块生成XML文件示例
2015/04/05 Python
python创建列表和向列表添加元素的实现方法
2017/12/25 Python
python3判断url链接是否为404的方法
2018/08/10 Python
基于numpy中数组元素的切片复制方法
2018/11/15 Python
使用python list 查找所有匹配元素的位置实例
2019/06/11 Python
python print出共轭复数的方法详解
2019/06/25 Python
在django-xadmin中APScheduler的启动初始化实例
2019/11/15 Python
jupyter 实现notebook中显示完整的行和列
2020/04/09 Python
next在python中返回迭代器的实例方法
2020/12/15 Python
澳大利亚拥有最好的家具和家居用品在线目的地:Nestz
2019/02/23 全球购物
库存图片、照片、矢量图、视频和音乐:Shutterstock
2021/02/12 全球购物
医药工作岗位求职信分享
2013/12/31 职场文书
学生期末评语大全
2014/04/30 职场文书
应届大学生自荐书
2014/06/17 职场文书
党的群众路线教育实践活动调研报告
2014/11/03 职场文书