通道阻塞的理解

laraverer發表於2021-06-04

當我們書寫goroutines協程時,大家或許遇到下面的報錯

fatal error: all goroutines are asleep - deadlock!

出現這個問題,就說明你的程式碼中管道是阻塞的:dizzy_face:

為了方便下次快速識別阻塞,遂進行如下總結

我們把channel看做成現實中的水管,水管的兩端分別代表代表著channel的接受端和傳送端。所以通道的阻塞自然有下面2種情況:

  1. 有接受端沒有傳送端或有傳送端沒有接受端(水管壓根就不通,這是致命的)

  2. 接受端和輸出端的速率不統一,造成的阻塞(接受端只接受一次,然後就關閉。所以接受端是阻塞的,因為channel是同步的,所以傳送端也停止的了工作)

上述兩種情況,就是我理解的阻塞,針對(1),這種情況是致命的,會出現文章開頭的錯誤。可以參考如下程式碼:

package main


func main() {

    out := make(chan int)
    out <- 2

}

針對(2)現象,這種情況系統不會爆出致命錯誤,但其本質也是阻塞的。可以參考如下程式碼:

package main

import "fmt"

func main() {
    ch1 := make(chan int)
    go pump(ch1)       // pump hangs
    fmt.Println(<-ch1) // prints only 0
}

func pump(ch chan int) {
    for i := 0; ; i++ {
        ch <- i
    }
}

:bowtie: :bowtie::bowtie:

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章