Open rhysh opened 2 years ago
Change https://go.dev/cl/406654 mentions this issue: runtime/pprof: slow new goroutine launches in test
The runtime does generally give some priority to new goroutines, because runtime.newproc
puts new goroutines in the runnext
slot, and runtime.findRunnable
(generally) prefers the local runq (of which runnext
is on top) over the global runq. Perhaps we are a bit too aggressive there.
runnext
does make the new goroutine share the same time slice with the parent goroutine (see inheritTime
here), but I suspect that churn
runs for such a short period of time that sysmon
's attempts to preempt it are generally unsuccessful [1].
[1] I think to succeed, it would need to preempt after churn
starts executing, but before it gets to the body of runtime.newproc
, which is realistically probably only a dozen or so instructions.
This is still prevalent in Go 1.22 and happens mostly when I am running the go test command with GOMAXPROCS = 1
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
The problem is present in Go 1.18 and in the development tip.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
What did you expect to see?
I expected each goroutine in the program to get a chance to run within a few 10ms scheduling intervals. The result of that would be for both wg.Done calls to execute, for the wg.Wait call to complete, and for the program to exit quickly without error.
What did you see instead?
When I run the test program with GOMAXPROCS=1, the new goroutine launches keep the runtime busy so it does not give all existing goroutines a chance to run. The goroutine that does nothing but call wg.Done does not get a chance to run until the timer expiration stops the new goroutine launches after 2000 milliseconds.
This isn't specific to GOMAXPROCS=1, additional calls to
go churn()
can keep additional scheduler threads busy.Refined from an original report in #52916. CC @golang/runtime