2026-07-30 15:52:50
Golang channel在以下情况下会被阻塞:
向未缓冲的channel发送数据(ch <- value):
阻塞条件:如果没有goroutine准备好从该channel接收数据,发送操作将被阻塞。在未缓冲的channel中,发送操作必须直接对应一个接收操作,即发送方在接收方准备好接收之前会一直阻塞。
从未缓冲的channel接收数据(value := <-ch):
阻塞条件:如果channel中没有数据可接收(即没有数据被发送到channel中),接收操作将被阻塞。接收方需要等待,直到有数据被发送到channel。
向已满的缓冲channel发送数据:
阻塞条件:对于缓冲channel,当缓冲区已满(即达到其容量)时,任何尝试向该channel发送更多数据的操作都会被阻塞,直到有足够的空间由于其他goroutine进行接收操作而被释放。
从空的缓冲channel接收数据:
阻塞条件:如果缓冲channel为空(即没有数据可以接收),从该channel接收数据的操作将被阻塞,直到有数据被发送到channel。
关闭的channel(与阻塞不完全相关,但需注意):
发送数据:尝试向一个已经关闭的channel发送数据会导致panic。
接收数据:从关闭的channel接收数据不会阻塞,并且总是立即返回。如果channel中有剩余的数据,将返回这些数据;否则,返回channel元素类型的零值。
select语句和default子句:
阻塞情况:在select语句中,如果所有的case都阻塞了,那么select语句会阻塞,直到至少一个case可以继续执行。
避免阻塞:如果select语句包含default子句,当所有的channel操作都阻塞时,将执行default子句,从而避免阻塞。
总结:
理解这些阻塞条件对于编写有效的并发程序以及避免死锁非常重要。在设计Go程序时,需要仔细考虑goroutines间的通信方式以及channel的使用方式,以确保程序既有效又安全。