如何操作系统.信号通道在 Go 内部处理?



当有代码时:

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没有,因为它的频道可能会遭受来自"外部"的写入,嗯, 它处理信号,它们来自程序外部。

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

谢谢!

您遇到死锁,因为尝试从通道接收消息,但没有其他正在运行的没有发送方的goroutine存在。同时,对signal.Notify的调用在后台watchSignalLoop()goroutine启动,您可以在此处验证实现详细信息 https://golang.org/src/os/signal/signal.go。

频道不关心元素类型,除非你的元素类型大于 64kB(严格来说,还有其他细微差别,请检查实现(。

不要猜测运行时是如何工作的,要研究一下。例如,您可以检查呼叫make(chan int)时会发生什么。您可以执行go tool compile -S main.go | grep main.go:line of make chan并检查从运行时包调用的函数。然后跳转到此文件并投入时间来了解实现。您会发现,与其他内容相比,通道的实现是薄而直接

的希望对您有所帮助!

最新更新