首頁  >  文章  >  後端開發  >  Append 函數對於並發 Goroutine 使用是執行緒安全的嗎?

Append 函數對於並發 Goroutine 使用是執行緒安全的嗎?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-11-18 21:53:02859瀏覽

Is Append Function Thread-Safe for Concurrent Goroutine Usage?

多個 Goroutine 並發使用時 Append 不是線程安全的嗎?

當使用 Goroutine 在循環內並發向切片追加資料時,您可能會遇到不一致的情況,例如缺少或重複的元素。這種情況提出了一個問題:append 函數對於多個 goroutine 並發使用是否不是線程安全的。

答案:資料爭用和缺乏線程安全

在Go 中,沒有任何值對於並發讀/寫是安全的,包括切片(或更具體地說,切片頭)。當多個 goroutine 嘗試同時修改同一個切片時,會發生資料爭用,可能會導致意外行為。

資料爭用驗證

您可以使用以下指令執行程式碼-競賽選項來確認資料競賽的存在:

go run -race play.go

解決方案:同步

為了解決這個問題並保證資料的一致性,需要在並發寫入元素時同步對切片的存取。這可以使用sync.Mutex來實現:

var mu = &sync.Mutex{}
destSlice := make([]myClass, 0)

var wg sync.WaitGroup
for _, myObject := range sourceSlice {
    wg.Add(1)
    go func(closureMyObject myClass) {
        defer wg.Done()
        var tmpObj myClass
        tmpObj.AttributeName = closureMyObject.AttributeName
        mu.Lock()
        destSlice = append(destSlice, tmpObj)
        mu.Unlock()
    }(myObject)
}
wg.Wait()

透過在追加到切片之前獲取互斥鎖並在之後釋放它,可以確保一次只有一個 goroutine 具有寫入存取權限,從而防止資料損壞。

結論

雖然切片元素表現為不同的變數並且可以修改同時,切片頭本質上並不是線程安全的。為了確保安全一致的並發寫入操作,在修改 goroutine 內的切片頭時採用同步機制(例如互斥鎖或通道)至關重要。

以上是Append 函數對於並發 Goroutine 使用是執行緒安全的嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn