繁体   English   中英

关于goroutine无限循环和memory分配的问题

[英]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 可能在技术上被挂起因为它们被标记为“现在不能运行,正在等待____”(填空)。)

另请参阅goroutines 是如何工作的? (或:goroutines 和 OS 线程的关系)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM