User-Level vs Kernel-Level Threads
- Process Management
- Memory Management
- Deadlocks
- OS Introduction & Fundamentals
- CPU Scheduling Algorithms
- Threads & Concurrency
- Inter-Process Communication (IPC)
- Process Synchronization
- Virtual Memory & Paging
- File Systems
- Disk Scheduling
- I/O Management
User-Level Threads: Managed Entirely Outside the Kernel
Kernel sees: [ One single process ]
Inside that process, a user-level thread library manages:
Thread A, Thread B, Thread C (invisible to the kernel)User-level threads are created and managed entirely by a library running in user space, without the kernel even being aware individual threads exist - to the kernel, it looks like one ordinary single-threaded process.
Kernel-Level Threads: Managed Directly by the OS
Kernel sees and directly schedules:
Thread A, Thread B, Thread C (each individually visible to, and managed by, the kernel)Kernel-level threads are created and scheduled directly by the operating system itself - the kernel has full visibility into each individual thread and can schedule them independently, including across multiple CPU cores.
Comparing the Two Approaches
| User-Level Threads | Kernel-Level Threads | |
|---|---|---|
| Creation/switching speed | Very fast - no kernel involvement needed | Slower - requires a kernel-mode transition |
| True multi-core parallelism | No - kernel only sees one schedulable unit | Yes - kernel can run threads on separate cores simultaneously |
| Blocking system call | Can block the entire process, all its threads included | Only that one specific thread blocks; others continue running |
Why the Blocking Behavior Difference Really Matters
If one user-level thread makes a blocking system call, the kernel - unaware other threads even exist within that process - can block the entire process, freezing every other thread too. Kernel-level threads don't have this problem, since the kernel can correctly recognize and independently manage each individual thread.
Why This Trade-off Motivated Hybrid Approaches
Neither pure approach is strictly better in every way - user-level threads are fast but can block unexpectedly; kernel-level threads avoid that but cost more per switch. This exact trade-off is precisely what the multithreading models covered in the next note attempt to balance.