How is a goroutine different from an OS thread?
A goroutine is a function running concurrently and scheduled by the Go runtime in user space. An OS thread is scheduled by the kernel. The main differences: Stack: a…
35 Go interview questions on goroutines & the scheduler, with detailed answers and code.
A goroutine is a function running concurrently and scheduled by the Go runtime in user space. An OS thread is scheduled by the kernel. The main differences: Stack: a…
The scheduler is built from three parts: G (goroutine): holds the goroutine's stack, saved registers ( gobuf ) and status ( _Grunnable , _Grunning , _Gwaiting ,…
When the current goroutine blocks or gives up the CPU, the P calls schedule() → findRunnable() . It checks these sources, roughly in order: Every 61st scheduling tick,…
package main import ( "fmt" "runtime" "sync" ) func main() { runtime.GOMAXPROCS(1) var wg sync.WaitGroup for i := range 5 { wg.Add(1) go func() { defer wg.Done()…
Before Go 1.14, preemption was cooperative . sysmon marked a goroutine that had run for more than about 10 ms by setting its stack guard to stackPreempt . The goroutine…
package main import ( "fmt" "runtime" "time" ) func main() { runtime.GOMAXPROCS(1) go func() { for { } }() time.Sleep(10 * time.Millisecond) fmt.Println("done") } Go…
Every non-leaf function begins with a stack check : it compares SP with g.stackguard0 . If the frame will not fit, the function calls runtime.morestack . That function…
GOMAXPROCS is the number of Ps, which is the maximum number of threads executing Go code at the same time. Threads blocked in syscalls or cgo do not count toward it. The…
Usually no . This question often catches people who are used to Java or C thread pools. In Go, a goroutine blocked on network I/O does not hold a thread or a P. It parks…
Before the syscall, the runtime calls entersyscall . The G moves to _Gsyscall , and its P moves to _Psyscall but stays attached to the M. The goal is to make fast…
The netpoller is a runtime layer over the OS readiness APIs: epoll on Linux, kqueue on BSD/macOS, IOCP on Windows. Sockets are opened in non-blocking mode. When…
sysmon is a runtime thread that runs without a P , so it keeps working even when every P is busy or stuck. It wakes up adaptively, every 20 µs to 10 ms, backing off when…
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…
LockOSThread ties the calling goroutine to its current M. That goroutine then always runs on that thread, and no other goroutine runs on it . The call nests: you need…
A goroutine leak is a goroutine that stays blocked forever, or runs forever, after its work no longer matters. It keeps its stack and everything that stack references,…
In production: Export runtime.NumGoroutine() as a metric and alert when it grows steadily. Use net/http/pprof . /debug/pprof/goroutine?debug=1 groups stacks with counts,…
The language sets no limit. In practice the limit is memory : at least about 2 KB of stack each, plus whatever each goroutine references. One million idle goroutines use…
The Go team left out goroutine IDs on purpose. With IDs, people would build goroutine-local storage , which hides dependencies and breaks as soon as work moves to…
package main import "fmt" func main() { go func() { defer fmt.Println("deferred") fmt.Println("in goroutine") }() fmt.Println("main done") } Most likely it prints only…
A panic that no one recovers, in any goroutine, crashes the whole process and prints that goroutine's stack. recover works only inside a deferred function in the same…
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup var mu sync.Mutex sum := 0 for i := 0; i < 3; i++ { wg.Add(1) go func() { defer wg.Done()…
The scheduler's checkdead function detects a deadlock only when no goroutine can make progress . That means there are no running Ms, and every remaining goroutine is…
Concurrency is about how a program is structured: independent tasks whose execution can interleave. Parallelism is about execution: several tasks running at literally…
The main G states in runtime2.go : _Gidle : just allocated. _Grunnable : in a run queue. _Grunning : owns an M and a P. _Gsyscall : in a syscall, owns an M but may lose…
GODEBUG=schedtrace=1000 prints a line every second with gomaxprocs , idleprocs , threads , spinningthreads , runqueue (global) and the per-P local queue lengths [..] .…
For CPU-bound work, only GOMAXPROCS goroutines can make progress at once. Adding more goroutines than that gives you no extra throughput. It does cost more: Switching…
A cgo call switches from the goroutine's small, movable stack to the M's system (g0) stack , because C needs a large stack that does not move. The runtime treats the…
Requirements: limit concurrency, stop the remaining work at the first error, wait for every goroutine to finish, and never block a sender forever. Without errgroup :…
Yes. net/http runs one goroutine per connection , and each request on that connection is handled in that goroutine (HTTP/2 uses one goroutine per stream). This works…
Since Go 1.14, timers live in a 4-ary heap per P . Before that, a single global timer goroutine handled them. The scheduler runs expired timers inside schedule() and…
runtime.Goexit() ends the calling goroutine after running all its deferred calls. A recover in those deferred calls returns nil, because Goexit is not a panic. t.FailNow…
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup x := 1 wg.Add(2) go func(v int) { defer wg.Done() fmt.Println("arg:", v) }(x) go func() { defer…
Two rules matter: The go statement that starts a goroutine is synchronized before the start of that goroutine. Writes the parent made before go are visible to the child.…
That profile shows scheduler overhead , not your code. It usually means the program creates or wakes many tiny goroutines, so Ps keep running out of work, spin looking…
synctest.Test(t, f) runs f in a new goroutine inside an isolated bubble . Goroutines started from it belong to the bubble, and the bubble has a fake clock that starts at…