我在并发方面缺少什么?

我有一个非常简单的脚本,它发出一个 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 例程时,程序需要更长的时间来执行。我在理解有效使用并发时缺少什么概念?


catspeake
浏览 143回答 1
1回答

慕虎7371278

您的示例的主要问题是您在wg.Wait()for 循环中调用。这使执行块,直到你推迟wg.Done()的呼叫内run。因此,执行不是并发的,它发生在 goroutine 中,但是在启动 goroutine 之后i和启动之前阻塞i+1。如果您将该语句放在循环之后而不是像下面那样,那么您的代码直到循环之后才会阻塞(所有 goroutine 都已启动,有些可能已经完成)。func main() {&nbsp; &nbsp; url := "http://finance.yahoo.com/q?s=aapl"&nbsp; &nbsp; for i := 0; i < 250; i++ {&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; go run(url, &wg)&nbsp; &nbsp; &nbsp; &nbsp; // wg.Wait() don't wait here cause it serializes execution&nbsp; &nbsp; }&nbsp; &nbsp; wg.Wait() // wait here, now that all goroutines have been started}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go