GoLang 記憶體模型文件指出以下程式碼可能會導致g 列印2 後接0:
var a, b int func f() { a = 1 b = 2 } func g() { print(b) print(a) } func main() { go f() g() }
此行為是由非同步性質引起的走常規。在執行任何函數之前,變數 a 和 b 被初始化為其各自的零值 (0)。 f() 函數修改這些變量,g() 函數隨後列印它們的值。
在 goroutine 中,語言規格確保讀取和寫入按照程式指定的順序發生。然而,操作的重新排序可能會在不影響 Goroutine 行為的情況下發生,這裡就是這種情況。
在 f() Goroutine 中,編譯器可以透過重新排序 b 和 a 的賦值來進行最佳化。由於 Goroutine 在賦值後不會使用這些變量,因此重新排序不會影響其行為。
另一方面,goroutine 之間的同步需要一致性。在同步點,編譯器保證所有賦值都已完成,確保 g() goroutine 讀取 a 和 b 時都已指派了值。這可確保正確列印修改後的值(2 和 1)。
以上是為什麼 Go 的並發執行會導致意外的變數值?的詳細內容。更多資訊請關注PHP中文網其他相關文章!