当有代码时:
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
并检查从运行时包调用的函数。然后跳转到此文件并投入时间来了解实现。您会发现,与其他内容相比,通道的实现是薄而直接
的希望对您有所帮助!