首頁  >  文章  >  後端開發  >  為什麼我的 Go 例程由於記憶體重新排序而列印出意外的值?

為什麼我的 Go 例程由於記憶體重新排序而列印出意外的值?

Susan Sarandon
Susan Sarandon原創
2024-11-23 06:58:17434瀏覽

Why Does My Go Routine Print Unexpected Values Due to Memory Reordering?

Go Routine 問題:同步不正確

您在 GoLang 中遇到的問題源自於其記憶體模型。根據文檔,在單一 Goroutine 中,只要不影響該 Goroutine 內的行為,就可以重新排序讀取和寫入。

考慮以下程式碼:

var a, b int

func f() {
    a = 1
    b = 2
}

func g() {
    print(b)
    print(a)
}

func main() {
    go f()
    g()
}

Due對於記憶體模型的重新排序,您可能會觀察到 g() 列印 2,然後列印 0。即使在 f() 中 a 的賦值出現在 b 之前,出於效率原因,編譯器可能會透過先指派 b 來最佳化程式碼。

在同一個 Goroutine 中,分配的順序是保證的,因為如果會導致問題,編譯器無法對它們重新排序。然而,在給定的例子中,兩個 goroutine 之間沒有同步。因此,編譯器不需要考慮重新排序對其他 goroutine 的潛在影響。

如果在 goroutine 之間引入同步,例如 WaitGroup 或互斥體,編譯器將確保不存在不一致在同步點。在這種情況下,您會期望 g() 會列印 2 和 1,因為這兩個賦值都會在 print() 呼叫之前完成。

理解 GoLang 記憶體模型的這一方面對於編寫並發程序和避免潛在的競爭條件或因意外重新排序而可能出現的其他問題。

以上是為什麼我的 Go 例程由於記憶體重新排序而列印出意外的值?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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