」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 為什麼我的 Goroutine 遞增變數會產生意外的結果?

為什麼我的 Goroutine 遞增變數會產生意外的結果?

發佈於2024-11-05
瀏覽:798

Why Does My Goroutine Incrementing a Variable Produce Unexpected Results?

這是編譯器最佳化的結果嗎?

在此程式碼片段中,啟動了一個 goroutine 並重複遞增變數 i:

package main

import "time"

func main() {
    i := 1
    go func() {
        for {
            i  
        }
    }()
    

然而,輸出總是1。這種行為可以歸因於Go記憶體模型和這段程式碼的具體實作。

Go內存模型

The Go 內存模型定義了在一個 Goroutine 中讀取變量時可以保證觀察到在不同 Goroutine 中寫入同一變量所產生的值的條件。它強調了同步對於並發存取共享資料的重要性。

省略同步

在給定的程式碼中:

  • 對i 的賦值(即i )後面沒有任何同步事件,表明更改可能不會立即對其他goroutine 可見。
  • 編譯器可以透過將其簡化為無操作來最佳化此循環最佳化。

編譯器最佳化

激進的編譯器可能會刪除i 語句,從而有效地將goroutine 縮減為:

for {}

同步範例

為了證明問題源自於缺乏同步,請考慮以下程式碼:

package main

import (
    "sync"
    "time"
)

func main() {
    mx := new(sync.Mutex)
    i := 1
    go func() {
        for {
            mx.Lock()
            i  
            mx.Unlock()
        }
    }()
    

在這種情況下,輸出不再是 1,而是一個很大的數字,正如預期的那樣。 sync.Mutex 提供同步並確保兩個 goroutine 以受控方式存取 i,允許 goroutine 遞增 i 並使變更對主例程可見。

最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3