首頁 > 後端開發 > Golang > 為什麼我的 Go WaitGroup 會導致'所有 Goroutine 都處於睡眠狀態 - 死鎖!”錯誤?

為什麼我的 Go WaitGroup 會導致'所有 Goroutine 都處於睡眠狀態 - 死鎖!”錯誤?

Barbara Streisand
發布: 2024-12-25 19:14:17
原創
755 人瀏覽過

Why Does My Go WaitGroup Cause a

WaitGroup 死鎖:理解「所有Goroutine 都處於睡眠狀態- 死鎖!」

當嘗試使用WaitGroup 可能協調會遇到錯誤「致命錯誤:所有goroutine 都在睡覺- 死鎖!」。當負責遞減 WaitGroup 計數器的 goroutine 無意中結束睡眠時,就會發生這種情況。

問題:

以下Go 程式碼說明如何出現此錯誤:

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            fmt.Println("Hello", i)
        }()
    }
    wg.Wait()
}
登入後複製

執行後,此程式碼應為每個goroutine 列印「Hello」。然而,程式卻以可怕的「死鎖」錯誤退出。

原因:

問題在於 WaitGroup 傳遞給 goroutine 的方式。當值傳遞給匿名函數時,Go 會產生該值的副本。因此,每個 goroutine 都在 WaitGroup 的單獨副本上運行,其中沒有一個副本的計數器遞減,從而導致 goroutine 永久睡眠。

解:

要解決死鎖,必須傳遞指向 WaitGroup 的指標而不是 WaitGroup 本身。因此,所有 goroutine 將引用相同的 WaitGroup,使它們能夠正確地遞減其計數器:

package main

import (
    "fmt"
    "sync"
)

func main() {
    wg := &sync.WaitGroup{}
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            fmt.Println("Hello", i)
        }()
    }
    wg.Wait()
}
登入後複製

透過傳遞指針,goroutines 共享相同的 WaitGroup 物件並可以成功協調它們的執行。此版本的程式碼將為每個 goroutine 正確列印“Hello”,而不會觸發死鎖。

以上是為什麼我的 Go WaitGroup 會導致'所有 Goroutine 都處於睡眠狀態 - 死鎖!”錯誤?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板