【问题标题】:question about goroutine infinite loop and memory allocation关于goroutine无限循环和内存分配的问题
【发布时间】:2019-10-31 16:59:05
【问题描述】:

所以我有一个程序需要分配一大块内存并永久保存。作为测试,我还运行了一个运行无限循环的 goroutine,在我的主线程中,我分配了内存,但是即使我将 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 将永远无法成功分配内存并打印“主线程 2”,即使我将 GOMAXPROCS 设置为 2,如果我在无限循环中打印一些东西,一切正常(这是预期的,因为 goroutine 在无限循环中打印一些东西,它调用系统调用并产生 cpu,所以我的主线程可以分配内存。

我想知道这是为什么?

【问题讨论】:

  • 这样的紧密循环不会给调度程序运行的机会。基本上......永远不要像这样运行一个紧密的循环。
  • 繁忙的循环始终是编程错误。您的代码中没有理由这样做。
  • 但没有将 GOMAXPROCS 设置为超过 1 意味着我可以拥有超过 1 个核心并且我的主线程也将有机会运行?
  • 你的主 goroutine 确实有机会运行,直到运行时期望中断繁忙循环并被阻塞。

标签: go memory goroutine


【解决方案1】:

你的底层计算机系统有一些线程执行器。 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 的点。

你可以自己从任何 goroutine 调用 runtime.Gosched 说:我自愿暂停自己,让其他想要运行的 goroutine 运行,直到执行者可以接我再次运行。 em> 许多其他系统调用此函数yield 或一些变体。 (注意“暂停”这个词:我在这里使用它是为了效果,但是调用 runtime.Gosched 的 goroutine 在技术上并没有暂停,因为它仍然被标记为“想要运行”,而其他 goroutine 可能在技术上被暂停,因为它们被标记为“现在无法运行,正在等待 ____”(填空)。)

另见How do goroutines work? (or: goroutines and OS threads relation)

【讨论】:

  • 即使我在 4 核机器上运行我的程序,主线程仍然无法继续。我想知道如何配置可以分配给我的 go 程序的系统线程执行器数量?
  • runtime.NumCPU 告诉你 Go 代码在启动时计算了多少个处理器。保留MAXPROCS 未设置,您将拥有这么多并发执行器可用。 “机器中的核心数”不一定是可以使用多少,因为这取决于您的操作系统等其他因素。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
  • 1970-01-01
  • 2021-04-30
  • 2021-08-27
  • 2011-03-24
  • 1970-01-01
  • 2023-01-24
相关资源
最近更新 更多