[英]question about goroutine infinite loop and memory allocation
所以我有一个程序需要分配一大块 memory 并永远持有它。 作为测试,我还运行了一个运行无限循环的 goroutine,在我的主线程中,我分配了 memory,但是即使我将 GOMAXPROCS 设置为大于 1,程序也会永远卡在 goroutine 的无限循环中。
func main() {
runtime.GOMAXPROCS(2)
go func() {
for {
//fmt.Printf("goroutine1\n")
}
}()
fmt.Println("main thread1")
x := [1145][1145]int{}
for i := 0; i < 1144; i++ {
fmt.Println(i)
x[i][i] = i
}
fmt.Println("main thread2")
}
如果我在无限循环中不做任何事情,我的主线程 1 将永远无法成功分配 memory 并打印“主线程 2”,即使我将 GOMAXPROCS 设置为 2,如果我在无限循环中打印一些东西,一切正常(这是预期的,因为goroutine在无限循环中打印一些东西,它调用系统调用并产生cpu,所以我的主线程可以分配memory。
我想知道为什么会这样?
你的底层计算机系统有一些线程执行器。 Go 运行时自己找出多少,并创建适当数量的运行时执行程序以使用所有系统。 更改 GOMAXPROCS 会更改运行时尝试分配的执行程序数量,但对底层系统没有影响。 在这种情况下,似乎底层系统本身只有一个执行者。
如果您的底层系统有两个或更多,Go 此时已经创建了两个执行程序,并将在其中一个上运行无限循环 goroutine,同时在另一个上运行您的main
goroutine。 但是由于您的系统只有一个,所以只有一个可以运行。 无论 Go 运行时可能创建多少运行时级别的执行程序,只有其中一个可以绑定到硬件 CPU 以实际运行。
请注意,goroutine 是多对 N 映射的。 例如,假设您拆分出 1000 个 goroutine,并拥有 10 个 CPU。 运行时将分配 10 个执行器并使用 10 个 CPU 一次运行 1000 个 goroutine 中的 10 个。 剩下的 990 个 goroutine 等到其中一个执行者达到自愿停止运行该goroutine 并选择剩余 990 个的点。
你可以从任何 goroutine 调用runtime.Gosched
自己,说:我自愿暂停自己,让其他想要运行的 goroutine 运行,直到执行器可以接我再次运行。 许多其他系统将此称为 function yield
或一些变化。 (注意“挂起”这个词:我在这里使用它是为了效果,但是调用runtime.Gosched
的 goroutine 在技术上并没有挂起,因为它仍然被标记为“想要运行”,而其他 goroutine 可能在技术上被挂起因为它们被标记为“现在不能运行,正在等待____”(填空)。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.