Golang / GoLang Concurrency Mastery Interview Questions
How does Go handle goroutines that make blocking syscalls — what happens to M and P?
When a goroutine makes a blocking OS syscall (file I/O, sleep), Go must not stall its P — other goroutines need to continue running. The runtime handles this through handoff: the P detaches from the blocked M and continues execution on a new M.
// What happens when goroutine G1 calls os.ReadFile (blocking syscall): // BEFORE SYSCALL: // P1 â M1 (running G1), G2/G3 in P1's local queue // ENTERING SYSCALL: // 1. M1 enters the OS kernel for the syscall // 2. Runtime detects M1 is in a syscall (can't schedule on M1) // 3. P1 detaches from M1 // 4. P1 acquires or creates a new M (M2) // 5. M2+P1 continues running G2, G3 ... // 6. M1 is a blocked kernel thread â parked in the OS // AFTER SYSCALL COMPLETES: // 7. M1 returns from the kernel; G1 is now runnable // 8. M1 tries to acquire any idle P // 9a. P available â M1+P runs G1 // 9b. No P idle â G1 to global run queue; M1 parks // WHY NET I/O SCALES BETTER: // Go wraps all socket I/O in non-blocking syscalls + epoll/kqueue (netpoller) // A goroutine doing net read â parks immediately (no M blocked in kernel) // When data arrives â epoll wakes â goroutine added to run queue // â Net goroutines hold no M while waiting for I/O // Practical consequence: // net/http server: 100K concurrent connections with ~GOMAXPROCS threads // File I/O: each blocking os.ReadFile ties up an M â scale carefully
More Related questions...