我有一个非常简单的脚本,它发出一个 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
}
- 1 回答
- 0 关注
- 142 浏览
添加回答
举报
0/150
提交
取消