我在兼并性方面缺少什么?

时间:2015-11-09 19:38:57

标签: go concurrency goroutine

我有一个非常简单的脚本,它会发出一个get请求,然后对响应做一些事情。我有2个版本一个使用go例程,一个没有我bencharmaked两个和速度没有区别。这是我正在做的一个愚蠢的版本:

正规版:

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)
    }
}

Go Routine:

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 个答案:

答案 0 :(得分:3)

您的示例的主要问题是您在for循环中调用wg.Wait()。这导致执行被阻止,直到您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
}