是什么导致空的 Go for 循环锁定程序?
What causes empty Go for loops to lock the program?
当我学习 Go 时,我最初使用一个空的 for 循环编写我的短程序来阻止程序退出,因为我 运行 我的测试函数使用 go 关键字。然而,随着我的 test/learning 程序大小的增长,整个程序有时会在 运行dom 位置冻结并且调试器会断开连接,从而使调试变得非常困难。
我最终从 IRC 上的一些讨论中了解到原因是空的 for 循环,并将其替换为阻塞通道,但除了与 Go 处理调度的方式有关外,我从未了解为什么.
后台是什么机制导致独立的 go-routines 锁定整个程序,即使有大量的内核分配给程序,如果有一个空的无限循环?
例如,问题 #10958:runtime: tight loops should be preemptible #10958
Currently goroutines are only preemptible at function call points.
Hence, it's possible to write a tight loop (e.g., a numerical kernel
or a spin on an atomic) with no calls or allocation that arbitrarily
delays preemption. This can result in arbitrarily long pause times as
the GC waits for all goroutines to stop.
In unusual situations, this can even lead to deadlock when trying to
stop the world. For example, the runtime's TestGoroutineParallelism
tries to prevent GC during the test to avoid deadlock. It runs several
goroutines in tight loops that communicate through a shared atomic
variable. If the coordinator that starts these is paused part way
through, it will deadlock.
空的 for 循环不会阻塞。它使 CPU 忙于一遍又一遍地执行相同的 JMP 指令。您应该已经听到您的 CPU 风扇旋转得相当快。
无限期阻塞的最简单方法是空 select 语句:
select {}
当我学习 Go 时,我最初使用一个空的 for 循环编写我的短程序来阻止程序退出,因为我 运行 我的测试函数使用 go 关键字。然而,随着我的 test/learning 程序大小的增长,整个程序有时会在 运行dom 位置冻结并且调试器会断开连接,从而使调试变得非常困难。
我最终从 IRC 上的一些讨论中了解到原因是空的 for 循环,并将其替换为阻塞通道,但除了与 Go 处理调度的方式有关外,我从未了解为什么.
后台是什么机制导致独立的 go-routines 锁定整个程序,即使有大量的内核分配给程序,如果有一个空的无限循环?
例如,问题 #10958:runtime: tight loops should be preemptible #10958
Currently goroutines are only preemptible at function call points. Hence, it's possible to write a tight loop (e.g., a numerical kernel or a spin on an atomic) with no calls or allocation that arbitrarily delays preemption. This can result in arbitrarily long pause times as the GC waits for all goroutines to stop.
In unusual situations, this can even lead to deadlock when trying to stop the world. For example, the runtime's TestGoroutineParallelism tries to prevent GC during the test to avoid deadlock. It runs several goroutines in tight loops that communicate through a shared atomic variable. If the coordinator that starts these is paused part way through, it will deadlock.
空的 for 循环不会阻塞。它使 CPU 忙于一遍又一遍地执行相同的 JMP 指令。您应该已经听到您的 CPU 风扇旋转得相当快。
无限期阻塞的最简单方法是空 select 语句:
select {}