How do goroutines interact with cgo, and why can cgo calls be expensive?
Question 174HardGo 1.22 to 1.25
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 call like a syscall (entersyscall), so if it runs long, sysmon hands off the P. Each call costs tens of nanoseconds, compared with about 1 ns for a Go call. It also blocks a whole thread for the duration.
Consequences:
- Many concurrent slow C calls mean many OS threads, possibly reaching the 10k limit.
- The C code cannot be preempted. A goroutine in C counts as being in a syscall, so a GC stop-the-world does not wait for it, but if it returns to Go during a STW it blocks until the world restarts.
- C code must not keep Go pointers after the call returns (cgo pointer rules; cheap checks are on by default with
GODEBUG=cgocheck=1, full checks needGOEXPERIMENT=cgocheck2since Go 1.21). - Callbacks from C threads into Go need an M. The runtime creates or borrows an "extra M", which adds cost.
- A C library with thread-local state needs
LockOSThread.
Mitigations:
- Batch work so that each C call does more.
- Limit concurrent C calls with a semaphore.
- Prefer pure-Go libraries. The pure-Go DNS resolver, for example, avoids a thread per lookup.
What the interviewer wants to hear: "cgo is not Go". It changes how scheduling, memory and deployment behave.
More on Goroutines & the Scheduler
- Q172How can you observe the scheduler? (schedtrace, go tool trace, pprof)
- Q173Why can many CPU-bound goroutines hurt performance, and how do you size a worker pool?
- Q175Implement a bounded, cancellable fan-out that returns the first error and does not leak goroutines.
- Q176Is creating a goroutine per request (e.g., in net/http) a good design? What are the risks?
- Q177How are timers handled by the scheduler, and what changed with time.Timer in Go 1.23?
- Q178What are the scheduling implications of runtime.Goexit, blocking in init, and unbuffered sends from many goroutines?