Golang / GoLang Concurrency Mastery Interview Questions
What is asynchronous preemption in Go (1.14+) and why was it introduced?
Before Go 1.14, goroutine scheduling was cooperative: a goroutine only yielded its processor at specific safe points — function call sites, channel operations, and syscalls. A CPU-bound goroutine in a tight loop with no function calls could starve other goroutines indefinitely and block GC stop-the-world phases.
// Pre-1.14: this goroutine could starve all others on its P indefinitely go func() { for { x := 0 for i := 0; i < 1_000_000_000; i++ { x++ } // No function calls â no scheduling point // Other goroutines on this P cannot run // GC STW cannot proceed â GC pause stretches indefinitely } }() // Go 1.14+: asynchronous preemption via SIGURG // sysmon goroutine detects a goroutine running on a P for > 10ms // It sends SIGURG to the OS thread running that goroutine // The signal handler inserts a preemption point; the goroutine yields // Effect: // - Tight loops no longer starve other goroutines // - GC STW completes in bounded time regardless of goroutine behaviour // - Programs are more responsive under CPU-heavy workloads // runtime.Gosched() â explicit cooperative yield (still useful) for i := 0; i < 1_000_000; i++ { doHeavyChunk(i) if i%1000 == 0 { runtime.Gosched() // voluntarily yield every 1000 iterations } } // Preemption safety: goroutine stacks may be moved during preemption // â All stack references must be valid Go pointers (enforces unsafe.Pointer rules)
More Related questions...