步骤顺序时使用goroutine

时间:2018-02-10 11:36:39

标签: go goroutine

我觉得我的问题的答案是肯定的,但要求确定,因为我只是开始玩Go几天。我们是否应该将IO绑定任务(如http请求)封装到goroutine中,即使它是用于顺序用例的?

这是我天真的例子。假设我有一个方法可以生成3个http请求但需要按顺序执行。创建invoke方法作为goroutines有什么好处吗?我理解下面的例子实际上会受到性能影响。

func myMethod() {
   chan1 := make(chan int)
   chan2 := make(chan int)
   chan3 := make(chan int)

   go invoke1(chan1)

   res1 := <-chan1
   invoke2(res1, chan2)

   res2 := <-chan2
   invoke3(res2, chan3)

   // Do something with <-chan3
}

我想到的一个可能的原因是,未来证明invoke方法,以便在其他开发重新使用该方法后在并发上下文中调用它们时。还有其他原因吗?

4 个答案:

答案 0 :(得分:5)

没有任何标准可以对这个问题说是或否。

虽然你可以通过这种方式正确地做到这一点,但坚持顺序执行要简单得多。

有三个理由浮现在脑海中:

  • 这仍然是顺序的:你依次等待每一个goroutine,所以这没有任何购买。如果只执行http请求,性能可能不会有太大变化,两种情况都会花费大部分时间等待响应。
  • 错误处理如果您只是获得result, err := invoke; if err != nil ....而不是通过渠道传递结果和错误就会简单得多
  • 过度概括是一个更贴切的词,而不是&#34;未来的证明&#34;。如果您将来需要异步调用invoke方法,请在将来更改您的代码。在函数周围添加异步包装器就好了。

答案 1 :(得分:1)

我参加派对有点晚了,但我想我还有一些事情要分享。

在回答这个问题之前,我想稍微深入一下Go Proverb,并发不是parellism 。对于goroutine和Go的语言特征,这是一个非常普遍的误解,当人们想到goroutine时,他们会考虑被剥夺的能力。

但正如Rob Pike在许多围棋谈判中所指出的那样,Go和goroutine实际上提供的是真实的。 Concurency是一个更好地融合现实世界,代码方式和结构,代码交互方式的模型。

回到这个问题。步骤顺序时应该使用goroutine吗?这取决于设计。如果你的代码由非常自然地相互通信的各个部分组成,或者你的某些代码保留了一个状态,并且经常return只是没有意义,或者如果你的代码适合任何其他的可靠性设计,它就是完全可以使用goroutine和channel以及select语句。 Rob Pike再次给出了现在Go text/template使用的词法分析器的Go Talk,其中词法分析器使用goroutine,但解析器显然只是顺序使用词法分析器。他表示,通过使用goroutine和channel,只需要一点点性能,就可以实现更好的API。

但另一方面,在你的例子中,可能你正在考虑的事情(代码可能需要未来的parellism),我同意@Marc。坚持阻止通话,至少目前是这样。

答案 2 :(得分:0)

您可以使用像buf这样的频道,或者使用[]字符串(字符串网址片段)。如果你只需要顺序执行,你就不会从gorutines中获得任何好处,因为我们无法控制goroutine。

但我们可以要求不要等runtime.Gosched()

来自文档: Gosched产生处理器,允许其他goroutines运行。它不会挂起当前的goroutine,因此执行会自动恢复。

顺序执行的示例:

package main

func main() {
    urls := []string{
        "https://google.com",
        "https://yahoo.com",
        "https://youtube.com",
    }
    buf := make([][]byte, 0, len(urls))
    for _, v := range urls {
        buf = append(buf, sendRequest(v))
    }
}

func sendRequest(url string) []byte {
    //send
    return []byte("")
}

答案 3 :(得分:-1)

对于这样的解决方案,我认为你在现实世界中解决问题没有任何好处。这并不意味着您的解决方案无法获益。如果您在练习后例如同步去例行程序,那么您将有大量的可能性进行实验和学习。

所以对我而言,这远不是一个明确的否定,但也不清楚是的。我不会说可能,这取决于你究竟是什么。您是在真正解决问题还是学习之后?