为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 工作线程池 - 从作业内部排队新作业

Golang 工作线程池 - 从作业内部排队新作业

Go
繁花不似锦 2022-09-05 10:46:44
我正在尝试同时从一组存储桶中构建一棵树,并且鉴于worker模式在go中似乎非常流行,我尝试将其应用于我的问题。基本上,我启动了一定数量的工人,让他们收听共享的工作渠道。然后,第一个工作线程接收树根节点作为第一个作业,并在分支和创建另外 2 个作业之前用相关信息填充它。然后,这些作业应该分布在其他工作者之间,然后这些工作线程将递归地生成更多的工作,直到整个树被构造出来。我的幼稚方法的简化表示类似于以下内容:func workers(count int) {    wg := sync.WaitGroup{}    wg.Add(count)    jobs := make(chan job)    for i := 0; i < count; i++ {        go func() {            // worker waits for job and then executes it            for j := range jobs {                processJob(j, jobs)            }            wg.Done()        }()    }    // start with some initial job    jobs <- job{}    wg.Wait()}func processJob(j job, jobs chan job) {    // jobs channel is closed when tree is finished    if done {        close(jobs)    }    // Do some more irrelevant stuff    // sometimes 2 new jobs result from this one    jobs <- job{}    jobs <- job{}    // but that doesn't work, if all workers try to send and no one receives}问题是,我无法从 1 个作业中添加 2 个新作业,因为在某些时候,每个工作线程都会忙于尝试将作业发送到通道,并且没有工作线程位于接收端。任何人都可以为我指出一个优雅的解决方案的方向,还是我对这个问题的整个方法都是错误的?
查看完整描述

1 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

如果没有其他工作人员准备好处理作业,请使用当前工作人员:


func doJob(j job, jobs chan job) {

    select {

    case jobs <- j:

    default:

        // Send to jobs was not ready, do the job

        // in the current worker.

        processJob(j, jobs)

    }

}

将 send 语句替换为调用 。jobs <- job{}doJob(job{}, jobs)


使用缓冲通道让工作线程保持忙碌:


jobs := make(chan job, N)

调整,直到找到一个工作人员大多忙的值。的一个好的起始值是 。此调整不是防止死锁所必需的。当 N 等于零时,程序不会死锁。NNcount


查看完整回答
反对 回复 2022-09-05
  • 1 回答
  • 0 关注
  • 67 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号