首頁 >後端開發 >Golang >為什麼我的 Go 程式會死鎖並出現'all goroutine are sleep”錯誤?

為什麼我的 Go 程式會死鎖並出現'all goroutine are sleep”錯誤?

DDD
DDD原創
2024-12-23 02:11:14904瀏覽

Why Does My Go Program Deadlock with the

Go 程式死鎖:「拋出:所有goroutine 都在睡眠」

在Go 程式中,當兩個或多個goroutine (並發運行的函數)無限期地等待彼此完成。使用通道時可能會出現一種這樣的情況,如以下程序所示:

package main

import (
    "fmt"
)

func total(ch chan int) {
    res := 0
    for iter := range ch {
        res += iter
    }
    ch <- res
}

func main() {
    ch := make(chan int)
    go total(ch)
    ch <- 1
    ch <- 2
    ch <- 3
    fmt.Println("Total is ", <-ch)
}

運行此程序將導致恐慌訊息:

throw: all goroutines are asleep - deadlock!

此問題的根本原因死鎖在於這樣一個事實:總goroutine 嘗試將一個值傳回它從(ch) 接收的相同通道。由於通道未關閉(發出完成訊號),整個 goroutine 中的範圍循環將無限期地繼續下去,從而阻塞任何進一步的發送或接收。

要解決此問題,我們可以引入另一個通道來接收結果。這是一個更新的程序:

package main

import (
    "fmt"
)

func total(in chan int, out chan int) {
    res := 0
    for iter := range in {
        res += iter
    }
    out <- res // Send result on separate channel
}

func main() {
    ch := make(chan int)
    rch := make(chan int) // New channel to receive result
    go total(ch, rch)
    ch <- 1
    ch <- 2
    ch <- 3
    close(ch) // Explicitly close channel to end loop in `total`
    result := <-rch // Wait for result on `rch`
    fmt.Println("Total is ", result)
}

透過在單獨的通道上發送結果並關閉原始通道,我們打破了僵局並允許主 goroutine 接收計算出的總數。

以上是為什麼我的 Go 程式會死鎖並出現'all goroutine are sleep”錯誤?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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