在学习Go时,我最初使用空的for循环编写了简短的程序,以阻止使用go关键字运行测试功能时退出程序。但是,随着我的测试/学习程序的增加,整个程序有时会在随机位置冻结,并且调试器会断开连接,从而使调试工作变得非常困难。
我从IRC上的一些讨论中最终了解到原因是空的for循环,并用阻塞通道代替了它,但是除了与Go处理调度有关的事情外,我什么都没学到。
即使有空的无限for循环,后台中有什么机制导致独立的go例程锁定整个程序,即使为该程序分配了很多内核?
答案 0 :(得分:3)
一个空的for循环不会阻塞。它使CPU忙于一次又一次地执行相同的JMP指令。您应该还听说过CPU风扇旋转得很快。
无限期阻止的最简单方法是一个空的select语句:
select {}
答案 1 :(得分:1)
例如,问题#10958:runtime: tight loops should be preemptible #10958
当前,goroutines仅在函数调用点可被抢占。 因此,有可能编写紧密循环(例如,数字内核 或旋转原子)而没有任意调用或分配 延迟抢占。这可能导致任意长的暂停时间,因为 GC等待所有goroutine停止。
在异常情况下,尝试执行以下操作甚至可能导致死锁 停止世界。例如,运行时的TestGoroutineParallelism 尝试在测试过程中防止GC以避免死锁。它运行几个 通过共享原子通信的紧密循环中的goroutines 变量。如果启动这些任务的协调员暂停了一半 通过,它将陷入僵局。