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

Time:09-12

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.

  • Related