Go 内部如何处理 os.Signal 通道?

有代码时:


package main


import (

    "os"

    "os/signal"

)


func main() {

    sig := make(chan os.Signal, 1)

    signal.Notify(sig)

    <-sig

}

运行没有问题,当然,阻塞直到你发送一个中断程序的信号。


但:


package main


func main() {

    sig := make(chan int, 1)

    <-sig

}

抛出此错误:


fatal error: all goroutines are asleep - deadlock!


goroutine 1 [chan receive]:

main.main()

    /home/user/project/src/main.go:5 +0x4d

exit status 2

虽然我理解为什么从int通道读取会导致死锁,但我只是怀疑它os.Signal不会,因为它的通道可能会遭受来自“外部”的写入,因为它处理信号并且它们来自程序外部。


我的怀疑有点正确吗?如果是这样,运行时如何处理与其他通道类型不同的情况?


谢谢!


慕哥6287543
浏览 171回答 1
1回答

湖上湖

您遇到了死锁,因为尝试从通道接收消息,但没有其他运行的没有发送者的 goroutine 存在。同时调用在后台signal.Notify启动watchSignalLoop()goroutine,您可以在此处验证实现细节https://golang.org/src/os/signal/signal.go。频道不关心元素类型,除非你的元素类型大于 64kB(严格来说,还有其他细微差别,请检查实现)。不要猜测运行时是如何工作的,对其进行研究。例如,您可以检查调用make(chan int).&nbsp;您可以go tool compile -S main.go | grep main.go:line of make chan检查从运行时包中调用了哪个函数。然后只需跳转到该文件并花时间了解实现。您会看到与其他事物相比,通道的实现非常简单明了希望能帮助到你!
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go