按顺序并发执行作业

时间:2019-04-17 14:42:19

标签: go concurrency sequential

“什么?”你问,“那个标题没有任何意义。”

请考虑以下内容: enter image description here 具有不同ID的作业可以异步处理,但是具有相同ID的作业应按照队列中的顺序进行同步处理。

我当前的实现创建了一个go例程来处理每个特定ID的作业,看起来像这样:

func FanOut() chan<- *Job {
    channel := make(chan *Job)
    routines = make(map[string]chan<- *Job)
    go func() {
        for j := range channel {
            r, found := routines[j.id]
            if !found {
                r = Routine()
                routines[j.id] = r
            }
            r <- j
        }
    }()
    return channel
}

这似乎很好(在当前测试中),但是创建数千个go例程可能不是最佳方法吗?另外,除非使用了缓冲通道,否则扇出代码块会消失。

我正在考虑使用sync.Mutex的集合,而不是上面的go例程的集合。想法是要有一个go例程例程,这些例程必须首先在对应于作业id的互斥锁上建立锁定。

是否存在适合处理这些需求的Go模式?

有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

为每个ID创建一个通道-可能是通道的一部分或地图(按ID索引)。每个通道都有一个例程,该例程按顺序处理该ID的作业。很简单。

我不会担心创建太多的例程。而且我不会使用互斥体-如果不使用通道进行过多的详细说明,那么go-routines只能一次只通过一个go-routine处理每个作业,并且避免了数据争用的可能性。

顺便说一句,我只是将其添加为答案,因为我不允许添加评论(还?)。