首頁 > 後端開發 > Golang > 陷入死鎖:為什麼會發生「拋出:所有 goroutine 都在睡覺」?

陷入死鎖:為什麼會發生「拋出:所有 goroutine 都在睡覺」?

Mary-Kate Olsen
發布: 2025-01-02 15:03:39
原創
558 人瀏覽過

Go Deadlock: Why Does

Go 中的死鎖:「拋出:所有goroutine 都在睡眠」

Go 程式中,當兩個或多個goroutine 等待時,就會發生死鎖彼此完成,導致凍結狀態,無法取得任何進展。這個問題經常被報告為「拋出:所有goroutine 都在睡眠- 死鎖!」

讓我們分析一個簡化的Go 程式來理解為什麼會發生這種死鎖:

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)
}
登入後複製

在這個程式中, Total 函數計算透過ch 通道發送的數字的總和,並將結果傳回同一通道。出現死鎖是因為滿足以下條件:

  • for 循環內的總函數區塊等待透過 ch 進行更多輸入(帶有 range 關鍵字)。
  • main 函數傳送向 ch 發送三個值,但不會關閉通道。
  • 由於Total 函數仍在等待更多輸入,因此不會將結果傳回ch.
  • main 函數在fmt.Println 行阻塞,等待ch.

這會產生死鎖情況,兩個goroutine(一個運行總和一個) in main) 正在等待對方採取行動,導致「拋出:所有goroutine都在睡眠」錯誤。

解決此問題死鎖,我們可以在發送最後一個值後關閉main 函數中的ch 通道:

ch <- 3
close(ch)
登入後複製

關閉通道向總goroutine 發出信號,表明沒有更多輸入,允許其完成計算並發送結果返回ch.

以上是陷入死鎖:為什麼會發生「拋出:所有 goroutine 都在睡覺」?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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