What does runtime.Gosched do and when (if ever) should you use it?
Question 160MediumGo 1.22 to 1.25
runtime.Gosched() gives up the processor. The current G goes to the global run queue as runnable, and the P schedules something else. It does not sleep or block, and the goroutine continues later without anything needing to wake it.
for !done.Load() {
runtime.Gosched() // polite spin — still a smell
}
Legitimate uses are rare:
- A cooperative yield inside a long CPU loop on Go versions before 1.14.
- Low-level lock-free code that briefly spins before parking.
- Making tests and demos show interleaving.
Since async preemption, it is almost never needed for fairness.
Gotchas:
- Gosched is not synchronization. Code that relies on it to order events is racy, and
-racewill say so. - A spin-wait with Gosched still burns CPU. Use channels,
sync.CondorWaitGroupinstead. - Compare it with
time.Sleep(0), which returns immediately, andruntime.Goexit(), which ends the goroutine after running its deferred calls.
More on Goroutines & the Scheduler
- Q158What is the netpoller and how does it make network I/O look blocking yet scale?
- Q159What is sysmon and what does it do?
- Q161What does runtime.LockOSThread do and when is it needed?
- Q162What is a goroutine leak? Give common causes.
- Q163How do you detect and debug goroutine leaks in production and tests?
- Q164How many goroutines can a Go program run? How do you bound them?