你能检测出给定数量的goroutine会创建多少个线程吗?

huangapple go评论135阅读模式
英文:

Can you detect how many threads a given number of goroutines will create?

问题

我了解到goroutine会被多个操作系统线程复用,所以如果一个goroutine被阻塞,比如在等待I/O时,其他goroutine会继续运行。但是有没有办法事先知道如果创建n个goroutine,会生成多少个线程呢?

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

type Vector []float64

// 对v中从i开始的n个元素应用操作。
func (v Vector) DoSome(i, n int, u Vector, c chan int) {
    for ; i < n; i++ {
        v[i] += u.Op(v[i])
    }
    c <- 1;    // 表示这一部分已完成
}
英文:

I understand that goroutines are multiplexed onto multiple OS threads, so if one should block, such as while waiting for I/O, others continue to run. But is there any way to know ahead of time how many threads I would spawn if I was to create n goroutines?

For example, if we call the function below would we know how many (or the maximum number of) system threads would be created for 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 &lt; n; i++ {
        v[i] += u.Op(v[i])
    }
    c &lt;- 1;    // signal that this piece is done
}

答案1

得分: 8

每个goroutine一次只能使用一个线程。它是否使用线程取决于它正在做什么。GOMAXPROCS的值决定了可以被自由运行的Go代码使用的线程数,换句话说,它决定了最大的并行级别。

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

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

  • 通道操作
  • 网络操作
  • 睡眠
  • sync包中的所有原语

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

英文:

Each goroutine can use a maximum of one thread at a time. Whether it uses a thread or not depends on what it's doing. The value of GOMAXPROCS determines the number of threads that can be used by freely running Go code - in other words, the maximum level of parallelism.

However more threads can be used, even with GOMAXPROCS=1, when goroutines block directly on system calls or calls into C.

The following operations do not cause the goroutine to use a thread when they block:

  • channel operations
  • network operations
  • sleeping
  • all primitives in the sync package

This means, for example, that if you have many goroutines that open /dev/ttyxx and block on read, you'll be using a thread for each one. Same goes if you're execing a load of processes and waiting for them to exit.

答案2

得分: 7

根据Pike的Go课程PDF幻灯片(第3天):

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

根据这篇博文,设置环境变量GOMAXPROCS似乎可以固定线程数。然而,如果你不指定这个值,我不确定运行时将管理多少个默认线程。

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

英文:

According to Pike's Go Course PDF slides (Day 3):

> ...if you want user-level parallelism you must set $GOMAXPROCS or call runtime.GOMAXPROCS(n). GOMAXPROCS tells the runtime scheduler how many non-syscall-blocked goroutines to run at once.

Based on this blog post, too, it would seem setting the environment variable GOMAXPROCS lets you fix the number of threads. I'm not sure how to get the default number of threads the runtime will manage if you do not specify this value, however.

This blog post seems to imply that if you do not set the environment variable the runtime will only utilize one core (presumably because it is only using one process.)

答案3

得分: 3

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

我不了解6g。

英文:

Currently, gccgo will create one thread per goroutine.

I don't know about 6g.

huangapple
  • 本文由 发表于 2009年11月11日 17:46:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/1714136.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定