我有一個非常簡單的腳本,它發(fā)出一個 get 請求,然后對響應(yīng)做一些事情。我有 2 個版本,第一個使用 go 例程,一個沒有我對兩者進(jìn)行基準(zhǔn)測試,速度沒有差異。這是我正在做的事情的一個愚蠢的版本:普通版: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)}在大多數(shù)情況下,當(dāng)我使用 go 例程時,程序需要更長的時間來執(zhí)行。我在理解有效使用并發(fā)時缺少什么概念?
1 回答

慕虎7371278
TA貢獻(xiàn)1802條經(jīng)驗 獲得超4個贊
您的示例的主要問題是您在wg.Wait()for 循環(huán)中調(diào)用。這使執(zhí)行塊,直到你推遲wg.Done()的呼叫內(nèi)run。因此,執(zhí)行不是并發(fā)的,它發(fā)生在 goroutine 中,但是在啟動 goroutine 之后i和啟動之前阻塞i+1。如果您將該語句放在循環(huán)之后而不是像下面那樣,那么您的代碼直到循環(huán)之后才會阻塞(所有 goroutine 都已啟動,有些可能已經(jīng)完成)。
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 關(guān)注
- 174 瀏覽
添加回答
舉報
0/150
提交
取消