运行Go简单应用程序时为什么会有更多的操作系统线程?

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

Why are there more OS threads when running go simple app?

问题

当运行一个简单的应用程序时,我的处理器允许的最大操作系统线程数比实际运行的线程数要多。

这是示例代码:

package main

import (
        "fmt"
        "runtime"
        "time"
)

func doSomething() {
        time.Sleep(10 * time.Minute)
}

func main() {
        maxProcs := runtime.GOMAXPROCS(0)
        numCPU := runtime.NumCPU()
        fmt.Println(maxProcs) // -> 打印 8
        fmt.Println(numCPU) // -> 打印 8
        for i := 0; i < 200; i++ {
                go doSomething()
        }
        time.Sleep(20 * time.Minute)
}

然后,运行以下命令:

go build main.go
./main

我可以看到与该进程相关的操作系统线程数超过了8个:

ps -T 15419
    PID    SPID TTY      STAT   TIME COMMAND
  15419   15419 pts/2    Sl+    0:00 ./main
  15419   15420 pts/2    Sl+    0:00 ./main
  15419   15421 pts/2    Sl+    0:00 ./main
  15419   15422 pts/2    Sl+    0:00 ./main
  15419   15423 pts/2    Sl+    0:00 ./main
  15419   15424 pts/2    Sl+    0:00 ./main
  15419   15425 pts/2    Sl+    0:00 ./main
  15419   15426 pts/2    Sl+    0:00 ./main
  15419   15427 pts/2    Sl+    0:00 ./main
  15419   15428 pts/2    Sl+    0:00 ./main
  15419   15429 pts/2    Sl+    0:00 ./main
  15419   15430 pts/2    Sl+    0:00 ./main 

据我所知,我应该只期望最多8个操作系统线程。为什么会超过这个数量呢?
谢谢!

编辑 #2
看来我对time.Sleep有了错误的理解。这篇帖子解释了Sleep是阻塞的,所以新增的操作系统线程是正常的。

编辑 #1
请纠正我如果我理解错了,根据官方文档

> GOMAXPROCS变量限制了可以同时执行用户级Go代码的操作系统线程数。在代表Go代码的系统调用中,被阻塞的线程数没有限制;它们不计入GOMAXPROCS的限制。

对于这个应用程序,应该只有8个操作系统线程。

英文:

When running a simple app, there are more OS threads than the max allowed by my processor.

This is the sample code:

package main

import (
        &quot;fmt&quot;
        &quot;runtime&quot;
        &quot;time&quot;
)

func doSomething() {
        time.Sleep(10 * time.Minute)
}

func main() {
        maxProcs := runtime.GOMAXPROCS(0)
        numCPU := runtime.NumCPU()
        fmt.Println(maxProcs) // -&gt; Prints 8
        fmt.Println(numCPU) // -&gt; Prints 8
        for i := 0; i &lt; 200; i++ {
                go doSomething()
        }
        time.Sleep(20 * time.Minute)
}

Then, when running:

go build main.go
./main

I can see more than 8 OS threads related with the process:

ps -T 15419
    PID    SPID TTY      STAT   TIME COMMAND
  15419   15419 pts/2    Sl+    0:00 ./main
  15419   15420 pts/2    Sl+    0:00 ./main
  15419   15421 pts/2    Sl+    0:00 ./main
  15419   15422 pts/2    Sl+    0:00 ./main
  15419   15423 pts/2    Sl+    0:00 ./main
  15419   15424 pts/2    Sl+    0:00 ./main
  15419   15425 pts/2    Sl+    0:00 ./main
  15419   15426 pts/2    Sl+    0:00 ./main
  15419   15427 pts/2    Sl+    0:00 ./main
  15419   15428 pts/2    Sl+    0:00 ./main
  15419   15429 pts/2    Sl+    0:00 ./main
  15419   15430 pts/2    Sl+    0:00 ./main 

As far as I know, I should expect upto 8 OS Threads only. Why do I get more than that?
Thanks!

Edit #2:
It seems I had a wrong understanding of time.Sleep. This post explains that Sleep is blocking, so the new OS Threads are expected.

Edit #1:
Please, correct me if I'm wrong, but I understand that, following pkg.go.dev/runtime documentation:

> The GOMAXPROCS variable limits the number of operating system threads that can execute user-level Go code simultaneously. There is no limit to the number of threads that can be blocked in system calls on behalf of Go code; those do not count against the GOMAXPROCS limit.

There should be 8 OS threads only for this application

答案1

得分: 4

你的问题的答案与这个问题有关。基本上,time.Sleep会阻塞Go协程,这样你就可以拥有超过GOMAXPROCS个协程运行,只要活动线程的数量不超过这个值。由于doSomething只是睡眠10分钟然后退出,对它的200次调用实际上对这个值没有任何贡献。

英文:

The answer to your question is related to this one. Essentially, time.Sleep blocks the go routine so it allows you to have more than GOMAXPROCS goroutines running so long as the number of active threads does not exceed this value. Since doSomething just sleeps for 10 minutes and then exits, all 200 calls to it effectively don't contribute to this value at all.

huangapple
  • 本文由 发表于 2022年9月12日 04:26:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/73682434.html
匿名

发表评论

匿名网友

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

确定