2 回答

TA貢獻1895條經(jīng)驗 獲得超7個贊
以下是代碼中的一些潛在問題:
i的值可能不是你所期望的
for i, st := range stu {
go func(st string){
studentList[i], err = getList(st)
if err != nil {
return ... //just example
}
}(st)
}
你啟動了一些goroutines,并在其中引用了。問題是,在你啟動 goroutine 的時間和 goroutine 引用它的時間之間,它可能已經(jīng)發(fā)生了變化(for 循環(huán)同時運行到它啟動的 goroutines)。很可能在任何 goroutines 之前的完成意味著所有輸出都將存儲在 的最后一個元素中(它們將相互覆蓋,因此您最終會得到一個值)。iiforstudentList
一個簡單的解決方案是傳遞到 goroutine 函數(shù)(例如 (這將創(chuàng)建一個副本)。有關(guān)詳細(xì)信息,請參閱此內(nèi)容。igo func(st string, i int){}(st, i)
學(xué)生列表的輸出
你沒有在問題中說,但我懷疑你在循環(huán)完成后立即運行(或類似)。如上所述,很可能在這一點上沒有一個goroutines完成(或者他們可能,你不知道)。使用 a 是一種相當(dāng)簡單的方法:fmt.Println(studentList[1]forWaitGroup
var wg sync.WaitGroup
wg.Add(len(stu))
for i, st := range stu {
go func(st string, i int) {
var err error
studentList[i], err = getList(st)
if err != nil {
panic(err)
}
wg.Done()
}(st, i)
}
wg.Wait()
我已經(jīng)在操場上糾正了這些問題。

TA貢獻1801條經(jīng)驗 獲得超8個贊
不是因為這個
goroutine執(zhí)行的順序不正常
這里至少有兩個問題:
您不應(yīng)該在 goroutine 中使用 for 循環(huán)變量。i
多個 goroutines 讀取 ,對于循環(huán)修改,這里是爭用條件。要按預(yù)期工作,請將代碼更改為:iii
for i, st := range stu {
go func(i int, st string){
studentList[i], err = getList(st)
if err != nil {
return ... //just example
}
}(i, st)
}
更重要的是,用來等待所有的goroutine。sync.WaitGroup
var wg sync.WaitGroup
for i, st := range stu {
wg.Add(1)
go func(i int, st string){
defer wg.Done()
studentList[i], err = getList(st)
if err != nil {
return ... //just example
}
}(i, st)
}
wg.Wait()
P.S.:(警告:也許并不總是這樣)
這條線,雖然它可能不會引起數(shù)據(jù)競爭,但它對CPU緩存線并不友好。最好避免編寫這樣的代碼。studentList[i], err = getList(st)
- 2 回答
- 0 關(guān)注
- 220 瀏覽
添加回答
舉報