使用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如何替换某个文件中的字符串
Apr 25 Golang
Go语言中break label与goto label的区别
Apr 28 Golang
浅谈Golang 嵌套 interface 的赋值问题
Apr 29 Golang
GoLang中生成UUID唯一标识的实现
May 08 Golang
Golang实现AES对称加密的过程详解
May 20 Golang
浅谈Golang 切片(slice)扩容机制的原理
Jun 09 Golang
Go timer如何调度
Jun 09 Golang
详解Go语言Slice作为函数参数的使用
Jul 02 Golang
Golang 并发下的问题定位及解决方案
Mar 16 Golang
Golang入门之计时器
May 04 Golang
Go 内联优化让程序员爱不释手
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获取随机数字和字母的方法详解
2013/06/06 PHP
五款PHP代码重构工具推荐
2014/10/14 PHP
fckeditor上传文件按日期存放及重命名方法
2015/05/22 PHP
浅析Yii2中GridView常见操作
2016/04/22 PHP
jQuery setTimeout()函数使用方法
2013/04/07 Javascript
jquery中获取元素里某一特定子元素的代码
2014/12/02 Javascript
纯javascript制作日历控件
2015/07/17 Javascript
基于Jquery实现焦点图淡出淡入效果
2015/11/30 Javascript
JS中setTimeout的巧妙用法前端函数节流
2016/03/24 Javascript
最细致的vue.js基础语法 值得收藏!
2016/11/03 Javascript
javascript 中模板方法单例的实现方法
2017/10/17 Javascript
基于jQuery的$.getScript方法去加载javaScript文档解析
2017/11/08 jQuery
Vue路由history模式解决404问题的几种方法
2018/09/29 Javascript
详解在React-Native中持久化redux数据
2019/05/22 Javascript
vue使用swiper实现中间大两边小的轮播图效果
2019/11/24 Javascript
jQuery实现本地存储
2020/12/22 jQuery
使用python提取html文件中的特定数据的实现代码
2013/03/24 Python
Python实现获取命令行输出结果的方法
2017/06/10 Python
python中使用iterrows()对dataframe进行遍历的实例
2018/06/09 Python
django admin后台添加导出excel功能示例代码
2019/05/15 Python
Django 用户认证组件使用详解
2019/07/23 Python
Python Web静态服务器非堵塞模式实现方法示例
2019/11/21 Python
在Django下创建项目以及设置settings.py教程
2019/12/03 Python
解决numpy矩阵相减出现的负值自动转正值的问题
2020/06/03 Python
python爬虫beautifulsoup解析html方法
2020/12/07 Python
欧洲顶级的童装奢侈品购物网站:Bambini Fashion(面向全球)
2018/04/24 全球购物
Skyscanner加拿大:全球旅行搜索平台
2018/11/19 全球购物
教师自我评价范例
2013/09/24 职场文书
教师绩效工资方案
2014/02/01 职场文书
《水上飞机》教学反思
2014/04/10 职场文书
技术负责人任命书
2014/06/05 职场文书
党的群众路线教育实践活动对照检查材料思想汇报
2014/09/19 职场文书
2014年小学英语教师工作总
2014/12/03 职场文书
2014年医院后勤工作总结
2014/12/06 职场文书
业务员年终工作总结2015
2015/05/28 职场文书
MySQL系列之七 MySQL存储引擎
2021/07/02 MySQL