使用golang编写一个并发工作队列
作者:u010278923 发布时间:2023-09-02 20:54:08
标签:golang,并发,队列
其实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)
以上为个人经验,希望能给大家一个参考
来源:https://chenxy.blog.csdn.net/article/details/72582200
0
投稿
猜你喜欢
- 这篇文章主要介绍了sql获取存储过程返回数据过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友
- 说明字符串驻留是一种仅保存一份相同且不可变字符串的方法。不同的值被存放在字符串驻留池中,发生驻留之后, 许多变量可能指向内存中的相同字符串对
- 一、闭包1.1 三要素 必须有一个内嵌函数内嵌函数必须引用外部函数中变量外部函数返回值必须是内嵌函数1.2 语法# 语法def 外部函数名(
- 由于曾经和他是同一个团队的,所以对于其我很熟悉他那“洁癖”的做法,对于他的很多的观点我也非常的赞同;但是有一件非常不理解的地方就
- 今天带你们去研究一个有趣的东西,文字识别OCR。不知道你们有没有想要识别图片,然后读出文字的功能。例如验证码,如果需要自动填写的话就需要这功
- 写入Excel中后有显示第一列客户款号总库存这些,开始写在第12行第一列开始写入,一行写入5个,然后再隔12行,再写入下边的数据,图片需要对
- 1. 列表1.1 复制浅拷贝list_1 = [1, [22, 33, 44], (5, 6, 7), {"name":
- urls.py:URL dispatcher(路由配置文件)URL配置(URLconf)就像是Django所支撑网站的目录。它的本质是URL
- 系列文章:PyQt5使用mimeData实现拖拽事件教程示例解析上实现思路1、简要介绍QMimeData2、QMimeData的用例1:在Q
- 前言Python 提供了很多截取字符串的方法,被称为“切片(slicing)”。模版如下:strin
- 通常报表都存储在一个地方,但是在单独的文件中。随着文件数量的增加在结构和搜索上也困难多多,针对这个问题,我遇到了一个非常有趣的报表对象属性&
- Create PROCEDURE Batch_Delete @TableName nvarchar(100), --表名 @FieldNam
- 一些大型站点都有着非常一流的视觉外观,它们很可能在设计时使用了网格系统。网格可以是页面布局显得紧凑而且稳定,为设计师在设计站点时提供一个逻辑
- 使用了application及结合数据库来保存统计数据 <html><head><title>
- Deepin安装开发环境 系统环境配置挂载分区1、挂载分区(需要先卸载分区):deepin:sudo mount -t ext4 /dev/
- 因为最近公司有python项目维护,所以把python的基础入门的书整理一遍,因为有些忘记了,同时在看<<python编程>
- Golang的接口是什么在 Golang 中,接口是一种类型,它是由一组方法签名组成的抽象集合。接口定义了对象应该具有的行为,而不关心对象的
- 在很多情况下,我们可能需要控制某一段代码只执行一次,比如做某些初始化操作,如初始化数据库连接等。 对于这种场景,go 为我们提供了 sync
- python是支持多线程的, 主要是通过thread和threading这两个模块来实现的,本文主要给大家分享python实现多线程网页爬虫
- 代码: <input type="text" value="fisker" onclick=&