通道阻塞的理解

当我们书写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 协议》,转载必须注明作者和本文链接
讨论数量: 1

deadlock只能说明死锁,不代表是因为管道阻塞而死锁 对于管道,通常由写入端控制管道的关闭,读取端判断管道状态来决定是否继续往下执行 随着main主协程的结束,全部子协程都会结束生命周期,第二段代码并不会造成资源的占用喝损失

1个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!