使用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中semaphore(信号量)源码
Apr 03 Golang
go原生库的中bytes.Buffer用法
Apr 25 Golang
Golang中interface{}转为数组的操作
Apr 30 Golang
golang fmt格式“占位符”的实例用法详解
Jul 04 Golang
Golang原生rpc(rpc服务端源码解读)
Apr 07 Golang
Go语言的协程上下文的几个方法和用法
Apr 11 Golang
Go语言 详解net的tcp服务
Apr 14 Golang
Golang 字符串的常见操作
Apr 19 Golang
Golang获取List列表元素的四种方式
Apr 20 Golang
Golang ort 中的sortInts 方法
Apr 24 Golang
GoFrame基于性能测试得知grpool使用场景
Jun 21 Golang
GoFrame框架数据校验之校验结果Error接口对象
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常见漏洞攻击分析
2016/02/21 PHP
Laravel框架实现发送短信验证功能代码
2016/06/06 PHP
注意!PHP 7中不要做的10件事
2016/09/18 PHP
PHP中list方法用法示例
2016/12/01 PHP
PHP cookie,session的使用与用户自动登录功能实现方法分析
2019/06/05 PHP
Laravel jwt 多表(多用户端)验证隔离的实现
2019/12/18 PHP
禁止刷新,回退的JS
2006/11/25 Javascript
JavaScript修改css样式style
2008/04/15 Javascript
javascript concat数组累加 示例
2009/09/03 Javascript
jquery 按键盘上的enter事件
2014/05/11 Javascript
JS实现倒计时和文字滚动的效果实例
2014/10/29 Javascript
js获取滚动距离的方法
2015/05/30 Javascript
jQuery.cookie.js实现记录最近浏览过的商品功能示例
2017/01/23 Javascript
基于vue开发的在线付费课程应用过程
2018/01/25 Javascript
fetch 如何实现请求数据
2018/12/20 Javascript
JS获取本地地址及天气的方法实例小结
2019/05/10 Javascript
微信小程序云开发如何实现数据库自动备份实现
2019/08/16 Javascript
Javascript异步编程async实现过程详解
2020/04/02 Javascript
再谈Python中的字符串与字符编码(推荐)
2016/12/14 Python
简单谈谈Python中的json与pickle
2017/07/19 Python
python先序遍历二叉树问题
2017/11/10 Python
Python工程师面试必备25条知识点
2018/01/17 Python
Python决策树之基于信息增益的特征选择示例
2018/06/25 Python
Pandas之排序函数sort_values()的实现
2019/07/09 Python
浅析PyTorch中nn.Linear的使用
2019/08/18 Python
使用python实现kNN分类算法
2019/10/16 Python
opencv3/C++实现视频背景去除建模(BSM)
2019/12/11 Python
广播电视新闻学专业应届生求职信
2013/10/08 职场文书
采购人员的个人自我评价
2014/01/16 职场文书
测试工程师程序员求职信范文
2014/02/20 职场文书
个性车贴标语
2014/06/24 职场文书
庆祝国庆节标语
2014/10/09 职场文书
2014年仓库管理工作总结
2014/12/17 职场文书
2015年社区统计工作总结
2015/04/21 职场文书
给原生html中添加水印遮罩层的实现示例
2021/04/02 Javascript
python 利用 PIL 将数组值转成图片的实现
2021/04/12 Python