首頁  >  文章  >  後端開發  >  為什麼下面的 go 程式會出現死鎖錯誤“致命錯誤:所有 goroutine 都在睡眠 - 死鎖!”

為什麼下面的 go 程式會出現死鎖錯誤“致命錯誤:所有 goroutine 都在睡眠 - 死鎖!”

PHPz
PHPz轉載
2024-02-09 08:00:11401瀏覽

为什么下面的 go 程序会出现死锁错误“致命错误:所有 goroutine 都在睡眠 - 死锁!”

在Go語言中,死鎖是一個常見的錯誤,當所有的goroutine都處於睡眠狀態時,就會出現致命錯誤:"致命錯誤:所有goroutine都在睡眠- 死鎖!"。這種情況通常發生在多個goroutine之間存在著互相等待的情況下。當一個goroutine等待另一個goroutine完成某個操作,而另一個goroutine又在等待第一個goroutine完成某個操作時,就會導致死鎖的發生。在這種情況下,程式無法繼續執行下去,因為所有的goroutine都無法繼續執行。為了避免死鎖錯誤的發生,我們需要仔細設計和管理goroutine之間的依賴關係,確保它們能夠正確地協同工作。

問題內容

我是 golang 新手,正在嘗試使用通路的一些典型生產者消費者。我知道生產者和消費者都應該從同一個通道寫入和讀取。但只是為了實驗,我讓他們從不同的管道寫入和讀取,如下所示

package main
    
    import (
        "fmt"
        "sync"
    )
    
    func main() {
    
        var wg sync.WaitGroup
        wg.Add(2)
    
        fmt.Println("Starting the main application")
    
        channel :=make( chan int)
        channel1 :=make( chan int)
    
    
        go generateNumbersV2(&wg, channel)
        go printNumbersV2(&wg, channel1)
    
    
        fmt.Println("Waiting for other goroutines")
        wg.Wait()
        //close()
        //close(channel)
    
        fmt.Println("All goroutines finished")
    }
    
    func printNumbersV2(wg *sync.WaitGroup, rc <-chan int) {
        defer wg.Done()
    
        for idx:=0 ;idx<3;idx++ {
    
            val := <-rc
            fmt.Println("******value received from channel ",val)
        }
    }
    
    func generateNumbersV2(wg *sync.WaitGroup, wc chan<- int) {
        defer wg.Done()
    
        for idx:=0 ;idx<3;idx++ {
    
             wc<-idx
            fmt.Println("###value written to channel ",idx)
        }
    
    }

當我運行該程式時,出現以下錯誤。

fatal error: all goroutines are asleep - deadlock!

現在,雖然我知道兩個 goroutine 都被阻塞,一個在對通道 1 的讀取呼叫上,另一個在對通道的寫入呼叫上被阻塞,因此程式永遠不會終止。 但我的問題是,如果實際上正在等待這些通道中的值,程式不應該無限期地等待而不是將其聲明為死鎖嗎?如果稍後由於某些網路讀/寫,值到達並且其他一些 go 例程寫入這些通道,該怎麼辦?

解決方法

只有當所有 goroutine 都在同步原語上被阻塞時,正在執行的程式才會因死鎖恐慌而終止。如果所有 goroutine 都被阻塞等待通道操作和/或互斥鎖,則無法進行網路接收,因為沒有 goroutine 正在偵聽網路連線。這也意味著,在一個有很多 goroutine 的程式中,你可能有很多死鎖的 goroutine 群組,但程式仍然繼續運行,因為還有其他 goroutine 仍然可以繼續運行。

以上是為什麼下面的 go 程式會出現死鎖錯誤“致命錯誤:所有 goroutine 都在睡眠 - 死鎖!”的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除