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

我在并发方面缺少什么?

我在并发方面缺少什么?

Go
catspeake 2021-11-22 15:17:58
我有一个非常简单的脚本,它发出一个 get 请求,然后对响应做一些事情。我有 2 个版本,第一个使用 go 例程,一个没有我对两者进行基准测试,速度没有差异。这是我正在做的事情的一个愚蠢的版本:普通版:func main() {    url := "http://finance.yahoo.com/q?s=aapl"    for i := 0; i < 250; i++ {        resp, err := http.Get(url)        if err != nil {            fmt.Println(err)        }        fmt.Println(resp.Status)    }}去日常:func main() {    url := "http://finance.yahoo.com/q?s=aapl"    for i := 0; i < 250; i++ {        wg.Add(1)        go run(url, &wg)        wg.Wait()    }}func run(url string, wg *sync.WaitGroup) {    defer wg.Done()    resp, err := http.Get(url)    if err != nil {        fmt.Println(err)    }    fmt.Println(resp.Status)}在大多数情况下,当我使用 go 例程时,程序需要更长的时间来执行。我在理解有效使用并发时缺少什么概念?
查看完整描述

1 回答

?
慕虎7371278

TA贡献1802条经验 获得超4个赞

您的示例的主要问题是您在wg.Wait()for 循环中调用。这使执行块,直到你推迟wg.Done()的呼叫内run。因此,执行不是并发的,它发生在 goroutine 中,但是在启动 goroutine 之后i和启动之前阻塞i+1。如果您将该语句放在循环之后而不是像下面那样,那么您的代码直到循环之后才会阻塞(所有 goroutine 都已启动,有些可能已经完成)。


func main() {

    url := "http://finance.yahoo.com/q?s=aapl"


    for i := 0; i < 250; i++ {

        wg.Add(1)

        go run(url, &wg)

        // wg.Wait() don't wait here cause it serializes execution

    }

    wg.Wait() // wait here, now that all goroutines have been started

}


查看完整回答
反对 回复 2021-11-22
  • 1 回答
  • 0 关注
  • 142 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信