Golang Go语言中读写一个nil通道会使协程永久挂起,为什么这样设计呢?
写了一个 demo: https://go.dev/play/p/51-Z_XNr-th
这里写一个 nil 通道会一直阻塞,Go 源码在这一行: https://hub.fastgit.xyz/golang/go/blob/go1.16.10/src/runtime/chan.go#L163
不知道为什么要这样设计?一直阻塞会导致协程泄漏,还不如直接 panic 掉,所以官方为什么这样做呢
.
.
.
Golang Go语言中读写一个nil通道会使协程永久挂起,为什么这样设计呢?
更多关于Golang Go语言中读写一个nil通道会使协程永久挂起,为什么这样设计呢?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你贴的这个直接运行
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send (nil chan)]:
main.main()
/tmp/sandbox3073028740/prog.go:11 +0x7e
goroutine 5 [chan receive]:
main.main.func1()
/tmp/sandbox3073028740/prog.go:9 +0x4f
created by main.main
/tmp/sandbox3073028740/prog.go:7 +0x6a
Program exited.
更多关于Golang Go语言中读写一个nil通道会使协程永久挂起,为什么这样设计呢?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
https://go.dev/ref/spec#Channel_types
A nil channel is never ready for communication.
> It’s for consistency with select. The semantics of a nil channel are
the same regardless of how it is used. It’s useful that it blocks in a
select, so that’s what it does outside a select.
> If it panicked outside a select, not only would it be inconsistent but
the channel code would need to behave differently in the two cases, a
needless complexity.
https://groups.google.com/g/golang-nuts/c/QltQ0nd9HvE/m/VvDhLO07Oq4J
在Golang(Go语言)中,通道(channel)是用于在多个goroutine(协程)之间进行通信的一种重要机制。关于读写一个nil通道会使协程永久挂起的设计,主要有以下几点原因:
-
明确的通信模式:Go语言强调通过通道进行显式通信来共享内存。如果允许对nil通道进行操作,可能会导致难以追踪的并发错误,因为开发者可能期望通道能够正常工作,而实际上通道并未被正确初始化。
-
避免潜在的死锁:如果允许对nil通道进行读写,且没有适当的错误处理机制,那么在某些情况下可能会导致死锁。因为协程会无限期地等待一个永远不会被发送或接收数据的通道。
-
鼓励安全的并发编程:强制要求在使用通道之前进行初始化,可以促使开发者更加谨慎地处理并发编程中的资源分配和同步问题。这有助于减少并发编程中常见的错误和漏洞。
-
一致性:在Go语言中,许多其他操作(如数组访问、映射查找等)在尝试访问无效或未初始化的资源时也会引发运行时错误或异常。对nil通道的操作采取类似的策略,可以保持语言行为的一致性。
综上所述,Go语言设计者对nil通道的操作采取了严格的限制,以防止潜在的并发错误和死锁问题。这种设计虽然可能增加了一些初始化的负担,但长远来看有助于提高程序的稳定性和可维护性。