OS & Systems FundamentalsCPU Scheduling & Context SwitchingHard⏱️ ~3 min

1:1 Threading vs M:N User Space Scheduling

1:1 Threading Model

In 1:1 threading, each user thread maps to one kernel thread. The OS scheduler manages all threads. Context switches go through the kernel. This is what Linux pthreads and Java threads use. Simple and well integrated with OS facilities like signals and blocking I/O.

The cost is kernel involvement on every context switch. Kernel mode transitions take 1 to 10 microseconds. With thousands of threads doing frequent switches, overhead becomes significant. Thread creation also requires kernel calls, costing 10 to 50 microseconds each.

M:N Threading and Goroutines

M:N threading maps M user space threads to N kernel threads. The runtime scheduler multiplexes user threads onto kernel threads. Switches happen in user space: no kernel calls, just register save and restore. Cost drops to 100 nanoseconds or less.

Go uses M:N scheduling. Goroutines are user space threads scheduled by the Go runtime. A program can have millions of goroutines but only as many kernel threads as cores. When a goroutine blocks on I/O, the runtime parks it and runs another. No kernel involvement unless the goroutine makes a system call.

Trade-offs

1:1 advantages: Full OS integration. Blocking calls work naturally. Debugging and profiling tools understand threads. Preemption is automatic and fair.

M:N advantages: Lightweight creation (goroutines cost 2 to 4 KB vs 1 MB for threads). Fast switching. Can support millions of concurrent tasks. Better for high concurrency with many short lived tasks.

M:N challenges: Blocking calls can block the kernel thread, starving other user threads. Runtimes must integrate with I/O carefully. Debugging is harder because OS tools see kernel threads, not user threads.

💡 Key Insight: M:N scheduling excels at high concurrency with many lightweight tasks. 1:1 threading works well for CPU bound workloads where kernel scheduling and preemption are needed. Choose based on your workload pattern.
💡 Key Takeaways
1:1 threading: each user thread is a kernel thread, 1 to 10 microsecond switches
M:N threading: many user threads on few kernel threads, 100 nanosecond switches
Goroutines cost 2 to 4 KB stack vs 1 MB for OS threads
M:N enables millions of concurrent tasks but complicates blocking and debugging
1:1 provides full OS integration; M:N provides lightweight concurrency
📌 Interview Tips
1Compare thread costs: Linux thread needs 1 MB stack minimum, goroutine starts at 2 KB and grows as needed
2Explain why Go can handle millions of connections: goroutines are user space scheduled, not kernel scheduled
3When discussing high concurrency, mention that M:N scheduling is why event loops and goroutines scale better than thread per connection
← Back to CPU Scheduling & Context Switching Overview