This simple example prints "done", "finished". How it's possible in case then we have only one physical thread limited by runtime.GOMAXPROCS(1)? Go 1.19
package main
import (
"fmt"
"runtime"
)
func main() {
runtime.GOMAXPROCS(1)
done := false
go func() {
done = true
fmt.Println("done")
}()
for !done {
}
fmt.Println("finished")
}
CodePudding user response:
GOMAXPROCS(1)
does not limit the program to a single thread. What does it do?
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;
Assuming that the scheduler is not considered "user-level Go code" in this context, it would not be constrained by this number (1).
Even if user code is really occupying all the available threads, user code can still often be preempted to allow other code to run. See the comment in preempt.go
for more details.
- Maybe "user-level" here is meant in the sense of user code vs. kernel code. In that case, the Go runtime scheduler is obviously not kernel code, but it would seem to be redundant to call it "user-level Go code".
CodePudding user response:
It's amazing to see so many negative ratings. At the same time, no one noticed that the reason for the change in the behavior of the go scheduler in 14.1 (https://go.dev/doc/go1.14 ) "goroutines are now asynchronously preemptible". This code should hang in versions up to 14.1 and work in later versions.