首頁  >  文章  >  後端開發  >  在 go 例程中使用兩個 fmt.println 時會出現死鎖嗎?

在 go 例程中使用兩個 fmt.println 時會出現死鎖嗎?

WBOY
WBOY轉載
2024-02-09 10:15:31812瀏覽

在 go 例程中使用两个 fmt.println 时会出现死锁吗?

在 Go 語言中,使用兩個 fmt.Println() 列印函數會導致死鎖嗎?這是一個常見的問題,讓我們來解答一下。首先,要了解死鎖的概念。死鎖是指兩個或多個進程互相等待對方完成的情況,導致程式無法繼續執行。在 Go 語言中,如果在兩個例程中同時使用 fmt.Println() 列印函數,由於標準輸出是線程安全的,所以不會出現死鎖的情況。因此,你可以放心地在 go 例程中使用多個 fmt.Println() 函數,而無需擔心死鎖問題。

問題內容

我正在嘗試學習 go,並且正在操場上進行實驗。我有一個非常簡單的程式碼。我試圖在 go 例程中一起使用結構和切片。我不確定這是否會是我在生產中使用的東西,但它似乎有點不對勁,所以這裡:

func main() {
    routinemsg := make(chan []Person)
    routinemsg2 := make(chan []Person)

    // create the person records
    p1 := newPerson("john doe", 25)
    p2 := newPerson("dohn joe", 52)
    p3 := newPerson("bohn joo", 30)

    // send a slice of Person to the first routine
    go func() { routinemsg <- []Person{p1, p2} }()

    // retrieve the slice from the first routine[in the append]
    // append p3 to the slice retrieved from the first routine
    // send the new slice to the second routine
    go func() { routinemsg2 <- append(<-routinemsg, p3) }()
    
    // I am able to see the first Println but when I insert the second one I get a deadlock error
    // also, same error if I use one Println with 2 arguments.
    fmt.Println(<-routinemsg)
    fmt.Println(<-routinemsg2)
}

我聽過等待群組,但還不了解它們!所以,對我好一點:d,感謝您抽出時間

解決方法

routinemsg 上只有一個發送操作,但您有2 個接收操作:一個在啟動的goroutine 中,另一個在main goroutine 中。發送的值只能由一個接收者接收一次。

如果啟動的goroutine先從routinemsg接收,那麼就會出現死鎖:main中的接收將永遠阻塞。

如果main goroutine 首先接收,那麼啟動的goroutine 將永遠阻塞(嘗試從中接收),因此它永遠無法在routinemsg2 上發送任何內容,因此main 中從routinemsg2 接收也將永遠阻塞:再次死鎖。

刪除main() 中的fmt.println(<-routinemsg) 行,然後從routinemsg2 的最終接收可以(最終)繼續並列印包含p1p2 和phpcnc 的切片phpcnp3:

[{john doe 25} {dohn joe 52} {bohn joo 30}]

go playground 上嘗試。

以上是在 go 例程中使用兩個 fmt.println 時會出現死鎖嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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