Go 通道缓冲和死锁

考虑以下代码块,预计会因达到缓冲区限制而引发错误:


package main        


import (

    "fmt"

    "time"

)


func main() {


    burstyLimiter := make(chan time.Time, 4)


    for i := 0; i < 5; i++ {

        burstyLimiter <- time.Now()

        fmt.Println("adding to burstyLimiter")

    }


}

但是,当我尝试使用以下确切块时,它会阻塞而不是抛出错误。我想了解这种行为。谢谢你的时间。


package main


import (

    "fmt"

    "time"

)


func main() {


    requests := make(chan int, 5)

    close(requests)


    limiter := time.Tick(time.Millisecond * 200)


    for req := range requests {

        <-limiter

        fmt.Println("request", req, time.Now())

    }


    burstyLimiter := make(chan time.Time, 4)


    for i := 0; i < 5; i++ {

        burstyLimiter <- time.Now()

        fmt.Println("adding to burstyLimiter")

    }

}


一只名叫tom的猫
浏览 111回答 1
1回答

九州编程

当 Go 运行时发现所有 goroutine 都处于死锁状态时,您会感到恐慌:等待某个“内部”事件,从某种意义上说是内部事件,另一个 goroutine 预计会触发它。这是你在第一个程序中得到的。在第二个程序中,您有一个“隐藏的”goroutine,它是通过调用time.Tick.&nbsp;这个 goroutine 在一个通道上发送滴答声,但不会阻塞它(“丢弃滴答声以弥补慢速接收器”来自文档)。所以在第二个例子中你至少有一个正在运行的 goroutine,它偶尔会阻塞外部事件(计时器滴答),因此从 Go 运行时死锁检测的角度来看,整个系统没有死锁。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go