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 (
"fmt"
"runtime"
"time"
)
func doSomething() {
time.Sleep(10 * time.Minute)
}
func main() {
maxProcs := runtime.GOMAXPROCS(0)
numCPU := runtime.NumCPU()
fmt.Println(maxProcs) // -> Prints 8
fmt.Println(numCPU) // -> Prints 8
for i := 0; i < 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
CodePudding user response:
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.