首頁 >後端開發 >Golang >為什麼 Go 的記憶體模型允許並發 Goroutine 中出現意外輸出?

為什麼 Go 的記憶體模型允許並發 Goroutine 中出現意外輸出?

Susan Sarandon
Susan Sarandon原創
2024-11-25 00:42:10267瀏覽

Why Does Go's Memory Model Allow Unexpected Output in Concurrent Goroutines?

Go Lang 中的不正確同步

Go 記憶體模型規定,在單一goroutine 中,讀取和寫入的行為必須像在程序指定的順序。然而,當使用多個goroutine 時,會出現一種奇怪的行為,如以下程式碼所示:

var a, b int

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

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

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

根據文檔,程式碼有可能先列印“2”,然後列印“0”,而不是預期的“1”和“2”。為什麼會發生這種情況?

儘管在程式碼中看起來是連續的,但在 f goroutine 中對 a 和 b 的賦值可能會亂序。由於 Goroutine 不會使用賦值後的變量,因此編譯器可以透過重新排序來最佳化。

但是 f 和 g goroutine 之間缺乏同步,表示編譯器無法確保列印時的一致性。因此,當兩個賦值發生在同一個 goroutine 時,b 的值可以先於 a 被觀察到。

為了確保正確性,goroutine 之間需要同步。在同步點,編譯器將保證兩個賦值都已完成。例如,如果在列印呼叫之前放置同步點,則新值(2 和 1)將被正確列印,從而防止錯誤行為。

以上是為什麼 Go 的記憶體模型允許並發 Goroutine 中出現意外輸出?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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