[英]Issue with goroutine and Waitgroup
我正在嘗試迭代一個循環並在匿名 function 上調用 go 例程,並在每次迭代中添加一個等待組。 並將字符串傳遞給相同的匿名 function 並將值附加到切片a 。 由於我循環 10000 倍的切片長度預計為 10000。但我看到隨機數。 不確定是什么問題。 誰能幫我解決這個問題?
這是我的代碼片段
import (
"fmt"
"sync"
)
func main() {
var wg = new(sync.WaitGroup)
var a []string
for i := 0; i <= 10000; i++ {
wg.Add(1)
go func(s string) {
a = append(a, s)
wg.Done()
}("MaxPayne")
}
wg.Wait()
fmt.Println(len(a))
}
請注意如何附加切片,實際上是創建一個新切片,然后將其分配回切片變量。 因此,您可以不受控制地並發寫入變量a
。 在 Go(和大多數語言)中並發寫入相同的值是不安全的。 為了使其安全,您可以使用互斥鎖序列化寫入。
嘗試:
var lock sync.Mutex
var a []string
和
lock.Lock()
a = append(a, s)
lock.Unlock()
有關互斥鎖如何工作的更多信息,請參閱教程和同步package 。
這是實現類似結果的模式,但不需要互斥體並且仍然是安全的。
package main
import (
"fmt"
"sync"
)
func main() {
const sliceSize = 10000
var wg = new(sync.WaitGroup)
var a = make([]string, sliceSize)
for i := 0; i < sliceSize; i++ {
wg.Add(1)
go func(s string, index int) {
a[index] = s
wg.Done()
}("MaxPayne", i)
}
wg.Wait()
}
這與您的其他程序不完全相同,但這就是它的作用。
即使沒有互斥體,memory 訪問現在也是安全的,因為每個 goroutine 只寫入其各自的索引(並且每個 goroutine 都有一個唯一的索引)。 因此,這些並發的 memory 寫入都不會相互沖突。 在最初創建具有所需大小的切片后,不需要再次分配變量a
本身,因此消除了原始的 memory 競爭。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.