首頁  >  文章  >  後端開發  >  交替印出奇數和偶數的 goroutine 陷入死鎖

交替印出奇數和偶數的 goroutine 陷入死鎖

王林
王林轉載
2024-02-13 16:00:101153瀏覽

交替打印奇数和偶数的 goroutine 陷入死锁

「交替列印奇數和偶數的 goroutine 陷入死鎖」是同時編程中常見的問題。在使用 goroutine 進行並發操作時,如果沒有正確的同步機制,很容易導致死鎖的情況發生。死鎖是指兩個或多個行程(或 goroutine)因為互相等待對方釋放資源而無法繼續執行的狀態。本文將介紹這個問題的原因,並提供解決方案,幫助開發者更好地理解並發程式設計中的死鎖問題。

問題內容

我目前正在學習golang。我想檢查 golang 通道是如何運作的。我創建了一個程序,其中兩個 goroutine 將交替列印奇數和偶數。即使程式列印正確,但最後仍顯示死鎖錯誤。從錯誤訊息中尚​​不清楚導致此問題的原因。

func main() {
    even := make(chan bool)
    odd := make(chan bool)
    go func() {
        defer close(odd)
        for i := 0; i <= 10; i += 2 {
            <-even
            print("even ====>")
            println(i)
            odd <- true
        }
    }()
    var wait sync.waitgroup
    wait.add(1)
    go func() {
        for i := 1; i <= 10; i += 2 {
            _, ok := <-odd
            if !ok {
                wait.done()
                return
            }
            print("odd ====>")
            println(i)
            even <- true
        }
    }()
    even <- true
    wait.wait()
}

[編輯] 謝謝大家的回覆。我編寫了以下程式碼來解決該問題。

func main() {
    even := make(chan bool)
    odd := make(chan bool)
    done := make(chan bool)
    //var wait sync.WaitGroup
    //wait.Add(2)
    go func() {
        for i := 0; i <= 10; i += 2 {
            <-even
            print("Even ====>")
            println(i)
            odd <- true
        }
        close(odd)
        close(even)
        done <- true
        // wait.Done()
    }()
    go func() {
        for i := 1; ; i += 2 {
            _, ok := <-odd
            if !ok {
                //wait.Done()
                return
            }
            print("Odd ====>")
            println(i)
            select {
            case even <- true:
            case <-done:
                return
            }
        }
    }()
    even <- true
    //wait.Wait()
    <-done
}

解決方法

問題可以透過以下方式解決

  1. 刪除第二個 gofunc 的 for 上限(第 20 行)
  2. selecting 寫入 even 時(第 28 行)

以上是交替印出奇數和偶數的 goroutine 陷入死鎖的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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