使用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 interface{}==nil 的几种坑及原理分析
Apr 24 Golang
Go语言带缓冲的通道实现
Apr 26 Golang
goland 清除所有的默认设置操作
Apr 28 Golang
Golang 使用Map实现去重与set的功能操作
Apr 29 Golang
解决golang post文件时Content-Type出现的问题
May 02 Golang
go类型转换及与C的类型转换方式
May 05 Golang
关于golang高并发的实现与注意事项说明
May 08 Golang
golang 实现并发求和
May 08 Golang
修改并编译golang源码的操作步骤
Jul 25 Golang
使用GO语言实现Mysql数据库CURD的简单示例
Aug 07 Golang
golang实现一个简单的websocket聊天室功能
Oct 05 Golang
golang生成vcf通讯录格式文件详情
Mar 25 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
Protoss热键控制
2020/03/14 星际争霸
ThinkPHP关联模型操作实例分析
2012/09/23 PHP
PHP数组无限分级数据的层级化处理代码
2012/12/29 PHP
php curl_init函数用法
2014/01/31 PHP
详细解读php的命名空间(一)
2018/02/21 PHP
JQuery插件开发示例代码
2013/11/06 Javascript
window.print打印指定div指定网页指定区域的方法
2014/08/04 Javascript
JavaScript中的alert()函数使用技巧详解
2014/12/29 Javascript
jquery通过ajax加载一段文本内容的方法
2015/01/15 Javascript
jquery实现LED广告牌旋转系统图片切换效果代码分享
2015/08/26 Javascript
javascript的document中的动态添加标签实现方法
2016/10/24 Javascript
jQuery将表单序列化成一个Object对象的实例
2016/11/29 Javascript
使用BootStrap进行轮播图的制作
2017/01/06 Javascript
js图片放大镜效果实现方法详解
2020/10/28 Javascript
angularjs指令之绑定策略(@、=、&amp;)
2017/04/13 Javascript
Vue 中批量下载文件并打包的示例代码
2017/11/20 Javascript
layui form表单提交后实现自动刷新
2019/10/25 Javascript
python使用socket向客户端发送数据的方法
2015/04/29 Python
Python从MP3文件获取id3的方法
2015/06/15 Python
在Python的Django框架中包装视图函数
2015/07/20 Python
Python实现的简单排列组合算法示例
2018/07/04 Python
Python(PyS60)实现简单语音整点报时
2019/11/18 Python
python 对象真假值的实例(哪些视为False)
2020/12/11 Python
马来西亚网上购物:Youbeli
2018/03/30 全球购物
工商管理专业实习生自我鉴定
2013/09/29 职场文书
自我鉴定四大框架
2014/01/17 职场文书
安全责任书范文
2014/03/12 职场文书
陈欧广告词
2014/03/14 职场文书
和睦家庭事迹
2014/05/14 职场文书
任命书怎么写
2014/06/04 职场文书
建筑节能汇报材料
2014/08/22 职场文书
2015年元旦主持词结束语
2014/12/14 职场文书
繁星春水读书笔记
2015/06/30 职场文书
《水上飞机》教学反思
2016/02/20 职场文书
InterProcessMutex实现zookeeper分布式锁原理
2022/03/21 Java/Android
Python中的socket网络模块介绍
2022/07/23 Python