首頁 >後端開發 >Golang >為什麼我的 Go 並發範例列印'6,6,6,6,6”而不是預期的順序?

為什麼我的 Go 並發範例列印'6,6,6,6,6”而不是預期的順序?

DDD
DDD原創
2024-11-29 12:26:11603瀏覽

Why Does My Go Concurrency Example Print

使用 for 迴圈和匿名函數實作 Go 並發:發現意外

在 Go 中編寫並發程式碼時,了解匿名函數的行為非常重要。在此範例中,我們探討了 for 迴圈和匿名函數產生意外輸出的場景。

初始程式碼

func main() {
    var wg sync.WaitGroup

    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go func() {
            fmt.Println(i)
            time.Sleep(time.Second * 1)
            wg.Done()
        }()
    }

    wg.Wait()
}

執行此程式碼令人驚訝地輸出「6, 6, 6, 6, 6」而不是預期的序列「2, 4, 1, 5, 3”。這是因為在 goroutine 啟動後,for 迴圈會繼續更新變數 i。

閉包

上面程式碼中的匿名函數是一個閉包。閉包捕獲創建函數體時使用的變數。在這種情況下,變數 i 在 Goroutine 啟動時被捕獲。然而,goroutine 啟動後,循環會繼續更新 i。

說明

由於循環直到 i 大於 5 才會終止,所以 goroutine 最終執行時 i 為 6。因此,每個 goroutine 都會列印閉包中捕獲的 i 值,在本例中為 6。只有當變數 i 作為參數傳遞給匿名函數時,才會觀察到預期的輸出,從而在呼叫時有效地建立該值的副本。

以上是為什麼我的 Go 並發範例列印'6,6,6,6,6”而不是預期的順序?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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