首頁 >後端開發 >Golang >為什麼 Go 程式會遇到'致命錯誤:所有 goroutine 都在睡眠 - 死鎖!”以及如何修復?

為什麼 Go 程式會遇到'致命錯誤:所有 goroutine 都在睡眠 - 死鎖!”以及如何修復?

Patricia Arquette
Patricia Arquette原創
2024-11-17 02:23:03251瀏覽

Why do Go programs encounter the

Go:死鎖恐慌- 了解原因並修復它

在Go 中,遇到的常見錯誤是「致命錯誤:所有goroutine 都睡著了—僵局!當 goroutine 陷入彼此等待對方繼續的狀態時,就會出現此錯誤。

問題陳述

考慮以下您想要閱讀的程式碼文字檔案中的一行單詞,將它們儲存在通道中,然後單獨列印它們:

func main() {
    f, _ := os.Open("D:\input1.txt")
    scanner := bufio.NewScanner(f)
    file1chan := make(chan string)
    for scanner.Scan() {
        line := scanner.Text()
        parts := strings.Fields(line)
        for i := range parts {
            file1chan <- parts[i]
        }
    }
    print(file1chan)
}

func print(in <-chan string) {
    for str := range in {
        fmt.Printf("%s\n", str)
    }
}

死鎖的原因

執行此程式碼時,您遇到死鎖錯誤。發生這種情況是因為通道 file1chan 未緩衝。因此,當您嘗試將值傳送到通道時,它會無限期地阻塞,等待接收者。

修補死鎖

要解決死鎖,您有兩個選擇:

  1. 使用緩衝通道:
    您可以透過將其大小指定為make(chan)的第二個參數來建立緩衝通道,像這樣:

    file1chan := make(chan string, 1) // buffer size of one

    緩衝通道就像一個數組,如果通道有可用容量,發送者可以在不阻塞的情況下發送值。

  2. 使用新的Goroutine:
    你可以啟動一個新的Goroutine 來傳送值給無緩衝通道:

    file1chan := make(chan string)
    go func() { // start a new goroutine that sends strings down file1chan
        for scanner.Scan() {
            line := scanner.Text()
            parts := strings.Fields(line)
            for i := range parts {
                file1chan <- parts[i]
            }
        }
        close(file1chan)
    }()
    
    print(file1chan)

    透過這種方式,新的Goroutine 承擔了發送值的責任,而主Goroutine 專注於列印它們。

透過實現這些解決方案中的任何一個,您可以有效地消除死鎖並實現 Goroutine 之間的順暢通訊。

以上是為什麼 Go 程式會遇到'致命錯誤:所有 goroutine 都在睡眠 - 死鎖!”以及如何修復?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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