使用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中的空slice案例
Apr 27 Golang
golang import自定义包方式
Apr 29 Golang
Golang 如何实现函数的任意类型传参
Apr 29 Golang
golang slice元素去重操作
Apr 30 Golang
golang DNS服务器的简单实现操作
Apr 30 Golang
go设置多个GOPATH的方式
May 05 Golang
go语言中GOPATH GOROOT的作用和设置方式
May 05 Golang
GoLang中生成UUID唯一标识的实现
May 08 Golang
Golang中channel的原理解读(推荐)
Oct 16 Golang
Go语言入门exec的基本使用
May 20 Golang
详解Go语言中Get/Post请求测试
Jun 01 Golang
Go语言测试库testify使用学习
Jul 23 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中计算中文字符串长度、截取中文字符串的函数代码
2011/08/09 PHP
PHP简单实现断点续传下载的方法
2015/09/25 PHP
thinkphp 框架数据库切换实现方法分析
2020/05/18 PHP
在网页中使用document.write时遭遇的奇怪问题
2010/08/24 Javascript
做好七件事帮你提升jQuery的性能
2014/02/06 Javascript
JS的get和set使用示例
2014/02/20 Javascript
使用AngularJS编写较为优美的JavaScript代码指南
2015/06/19 Javascript
基于JavaScript实现轮播图代码
2016/07/14 Javascript
jQuery鼠标事件总结
2016/10/13 Javascript
node.js调用Chrome浏览器打开链接地址的方法
2017/05/17 Javascript
详解VueJs前后端分离跨域问题
2017/05/24 Javascript
JavaScript之DOM插入更新删除_动力节点Java学院整理
2017/07/03 Javascript
详解使用angularjs的ng-options时如何设置默认值(初始值)
2017/07/18 Javascript
详解基于vue的移动web app页面缓存解决方案
2017/08/03 Javascript
bootstrap模态框嵌套、tabindex属性、去除阴影的示例代码
2017/10/17 Javascript
Vue用v-for给src属性赋值的方法
2018/03/03 Javascript
Vue 中的受控与非受控组件的实现
2018/12/17 Javascript
js常用正则表达式集锦
2019/05/17 Javascript
Vue.js项目实战之多语种网站的功能实现(租车)
2019/08/07 Javascript
微信小程序引入VANT组件的方法步骤
2019/09/19 Javascript
解决vue项目中页面调用数据 在数据加载完毕之前出现undefined问题
2019/11/14 Javascript
JQuery样式与属性设置方法分析
2019/12/07 jQuery
vue中element 的upload组件发送请求给后端操作
2020/09/07 Javascript
python遍历文件夹找出文件夹后缀为py的文件方法
2018/10/21 Python
Python 实现王者荣耀中的敏感词过滤示例
2019/01/21 Python
详解Python3定时器任务代码
2019/09/23 Python
使用Python函数进行模块化的实现
2019/11/15 Python
Python导入模块包原理及相关注意事项
2020/03/25 Python
HTML5拍照和摄像机功能实战详解
2019/01/24 HTML / CSS
中式婚礼主持词
2014/03/13 职场文书
基层工作经验证明样本
2014/11/16 职场文书
幼儿园门卫安全责任书
2015/05/08 职场文书
2015年乡镇平安建设工作总结
2015/05/13 职场文书
2015最新婚礼司仪主持词
2015/06/30 职场文书
2016大学生就业指导课心得体会
2016/01/15 职场文书
安装Windows Server 2012 R2企业版操作系统并设置好相关参数
2022/04/29 Servers