Go 例程阻塞其他:更深入的解释
在 Go 中,以下代码表现出一种不寻常的行为,其中一个具有无限循环的 goroutine 似乎阻止另一个 Goroutine 的消息到达预期的通道:
func main() { timeout := make(chan int) go func() { time.Sleep(time.Second) timeout <- 1 }() res := make(chan int) go func() { for { } res <- 1 }() select { case <-timeout: fmt.Println("timeout") case <-res: fmt.Println("res") } }
相反一秒后终止,程序进入无限循环。为什么会发生这种情况?
理解 Go 中的协作调度
答案在于 Go 对 goroutine 的协作调度的使用。 Goroutine 在某些条件下将控制权交给调度程序,包括:
由于第一个 Goroutine 中的无限循环永远不会产生,它会阻止其他 Goroutine 运行并向通道发送消息。这包括超时通道,它正在等待一条永远不会到达的消息。
潜在的解决方案
虽然协作调度可能会导致这种情况,但还是有潜在的解决方案:
以上是为什么 Infinite Go 例程会阻止其他 Goroutine 发送到通道?的详细内容。更多信息请关注PHP中文网其他相关文章!