根据依赖关系在Go中执行任务

huangapple go评论68阅读模式
英文:

Execute task based on dependencies in Go

问题

我认为这更多是关于逻辑而不是Go语言本身的问题。
我想找到一种在Go语言中基于依赖关系执行任务的方法。

考虑上面的工作流程:
任务1、2、3和4可以同时异步运行。
当任务1和2完成时,将执行任务10。
当任务3和4完成时,将执行任务11。
当任务11和12完成时,将执行任务12。
当任务10和11完成时,将执行任务100。

我正在使用Go通道来进行并发执行,并希望找到一种有效控制依赖关系的方法。我知道我可以使用某种标志和表来控制执行,但理想情况下,我希望在内存中完成,以避免对数据库的调用来控制这样的事情。
我也明白有几种方法可以做到这一点,但我想听听你的想法,因为我相信肯定有比我目前想出的方法更好的方法。

英文:

I think this more of a question about logic than go itself.
I want to find a way to execute a task based on its dependencies in go language.

根据依赖关系在Go中执行任务

Considering the workflow above:
Task 1,2,3 and 4 can be ran asynchronously at the same time.
Task 10 will be executed when Task 1 and 2 is finished.
Task 11 will be executed when Task 3 and 4 is finished
Task 12 will be executed when Task 11 and 12 is finished
Task 100 will be executed when Task 10 and 11 is finished.

I'm using go channels to make the concurrent executions and want to find an effective way to control the dependencies. I know I could have some sort of flag and a table to control execution but ideally I would like to do it in memory to avoid the database calls to control such thing.
I also understand that there are several ways of doing this, but would like to hear your ideas because I'm sure there is a better way of doing than the ways I could come up with so far.

答案1

得分: 5

在这个主题上有一个有趣的reddit帖子,是对文章"如何在继续之前等待所有Goroutine执行完毕"的回应。

正确的文章是"如何在继续之前等待所有Goroutine执行完毕,第二部分:修复我的错误",并且介绍了几种在继续执行另一个任务之前等待Goroutine的方法。

根据你要同步的任务的信息类型,sync.WaitGroup是一个很好的选择(如此示例所示)。

但是:

> 当你知道要期望的消息数量时,你可以计数它们以知道何时完成。在这种情况下,WaitGroup是多余和令人困惑的。

以下代码将阻塞,直到收到所有3个消息:

func main() {
  messages := make(chan int)
  go func() {
      time.Sleep(time.Second * 3)
      messages <- 1
  }()
  go func() {
      time.Sleep(time.Second * 2)
      messages <- 2
  }()
  go func() {
      time.Sleep(time.Second * 1)
      messages <- 3
  }()
  for i := 0; i < 3; i++ {
      fmt.Println(<-messages)
  }
}

所以,这真的取决于你对等待的任务了解多少。

英文:

There was an interesting reddit thread on that topic, in response to the article "How to Wait for All Goroutines to Finish Executing Before Continuing".

The correct article is "How to Wait for All Goroutines to Finish Executing Before Continuing, Part Two: Fixing My Oops" and illustrates several ways to wait for goroutines before carrying on with another task.

Depending on the kind of information you have for the tasks to synchronize, sync.WaitGroup is a good candidate (as in this example).

But:

> When you know the number of messages to expect you might as well count them to know when to finish. Here the WaitGroup is superfluous and confusing.

This would block until all 3 messages are received:

func main() {
  messages := make(chan int)
  go func() {
      time.Sleep(time.Second * 3)
      messages &lt;- 1
  }()
  go func() {
      time.Sleep(time.Second * 2)
      messages &lt;- 2
  }()
  go func() {
      time.Sleep(time.Second * 1)
      messages &lt;- 3
  }()
  for i := 0; i &lt; 3; i++ {
      fmt.Println(&lt;-messages)
  }
}

So it really depends on what you know from the tasks you are waiting for.

huangapple
  • 本文由 发表于 2014年7月11日 13:50:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/24690847.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定