8

我知道 goroutine 被多路复用到多个操作系统线程上,所以如果一个应该阻塞,比如在等待 I/O 时,其他的会继续运行。但是有没有办法提前知道如果我要创建 n 个 goroutine 会产生多少线程?

例如,如果我们调用下面的函数,我们是否知道将为 n 个 goroutine 创建多少(或最大数量)系统线程:

type Vector []float64

// Apply the operation to n elements of v starting at i.
func (v Vector) DoSome(i, n int, u Vector, c chan int) {
    for ; i < n; i++ {
        v[i] += u.Op(v[i])
    }
    c <- 1;    // signal that this piece is done
}
4

3 回答 3

8

每个 goroutine 一次最多可以使用一个线程。它是否使用线程取决于它在做什么。GOMAXPROCS 的值决定了自由运行 Go 代码可以使用的线程数——也就是最大并行度。

然而,即使 GOMAXPROCS=1,当 goroutine 直接阻塞系统调用或对 C 的调用时,也可以使用更多线程。

以下操作在阻塞时不会导致 goroutine 使用线程:

  • 渠道运营
  • 网络运营
  • 睡眠
  • 同步包中的所有原语

这意味着,例如,如果您有许多打开 /dev/ttyxx 并在读取时阻塞的 goroutine,那么您将为每个 goroutine 使用一个线程。如果您正在执行大量进程并等待它们退出,情况也是如此。

于 2012-05-25T11:55:12.150 回答
7

根据派克的围棋课程 PDF 幻灯片(第 3 天):

...如果您想要用户级并行性,您必须设置$GOMAXPROCS或调用runtime.GOMAXPROCS(n). GOMAXPROCS告诉运行时调度程序一次运行多少个非系统调用阻塞的 goroutine。

同样基于此博客文章,设置环境变量似乎GOMAXPROCS可以让您修复线程数。但是,如果您不指定此值,我不确定如何获取运行时将管理的默认线程数。

这篇博文似乎暗示,如果你不设置环境变量,运行时将只使用一个核心(大概是因为它只使用一个进程。)

于 2009-11-12T23:38:38.087 回答
3

目前,gccgo 将为每个 goroutine 创建一个线程。

不知道6g。

于 2009-11-11T13:57:39.183 回答