我知道goroutine被多路复用到多个OS线程上,因此如果应该阻塞,例如在等待I / O时,其他人继续运行。但有没有办法提前知道如果要创建n个goroutines,我会产生多少个线程?
例如,如果我们调用下面的函数,我们就知道将为n个goroutines创建多少(或最大数量)系统线程:
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
}
答案 0 :(得分:7)
根据派克的Go课程PDF幻灯片(第3天):
...如果您想要用户级并行,则必须设置
$GOMAXPROCS
或致电runtime.GOMAXPROCS(n)
。GOMAXPROCS
告诉运行时调度程序一次运行多少非系统调用阻塞的goroutine。
基于this blog post,似乎设置环境变量GOMAXPROCS
可以修复线程数。但是,如果你没有指定这个值,我不确定如何获得运行时将管理的默认线程数。
This blog post似乎暗示如果你没有设置环境变量,运行时只会使用一个核心(大概是因为它只使用一个进程。)
答案 1 :(得分:7)
每个goroutine一次最多可以使用一个线程。它是否使用线程取决于它正在做什么。 GOMAXPROCS的值决定了自由运行Go代码可以使用的线程数 - 换句话说,就是最大并行级别。
然而,当goroutines直接阻止系统调用或调用C时,可以使用更多线程,即使GOMAXPROCS = 1。
以下操作 not 导致goroutine在阻止时使用线程:
这意味着,例如,如果您有许多goroutine打开/ dev / ttyxx并在读取时阻塞,那么您将为每个使用一个线程。如果您正在执行一系列进程并等待它们退出,也是如此。
答案 2 :(得分:3)
目前,gccgo将为每个goroutine创建一个线程。
我不知道大约6g。