A topic in the Open Knowledge Graph — a free, open map of 15,290 topics and the order to learn them in.

Thread Models: User-Level and Kernel Threads

College Depth 94 in the knowledge graph ☐ I know this ☆ Set as goal
45topics build on this
356prerequisites beneath it
See this on the map →
Processes and the Process Control Block→→Thread Creation and Lifecycle
threading lightweight-concurrency kernel-vs-user

Core Idea

Threads are lightweight execution units sharing an address space within a process. User-level threads are scheduled by user-space libraries, reducing kernel overhead but limiting parallelism to one thread per process. Kernel threads are scheduled by the OS, enabling true parallelism. Hybrid models (M:N) attempt to balance overhead and parallelism.

Explainer

You already know that a process has its own address space, registers, and resources. A thread is a way to have multiple streams of execution within a single process, all sharing the same memory and open files but each with its own program counter, register set, and stack. If a process is like a house, threads are the people living in it — they share the kitchen and living room (memory, file handles) but each has their own to-do list (instruction pointer) and personal workspace (stack). The critical question is: who manages these threads?

User-level threads are managed entirely by a library in user space — the operating system doesn't even know they exist. The thread library handles creation, scheduling, and switching between threads, all without making system calls. This makes thread operations extremely fast: creating a user-level thread or switching between them might take microseconds rather than the tens of microseconds a kernel call would cost. The tradeoff is severe, though. Because the OS sees only one process, it schedules that process onto one CPU core. If you have four user-level threads, they take turns running on that one core — you get concurrency (interleaved execution) but not parallelism (simultaneous execution). Even worse, if one user-level thread makes a blocking system call (like a disk read), the entire process blocks, freezing all threads, because the kernel doesn't know there are other threads that could keep running.

Kernel-level threads solve these problems by making the OS aware of each thread. The kernel schedules threads individually, so different threads in the same process can run on different CPU cores simultaneously — true parallelism. If one thread blocks on I/O, the kernel simply schedules another thread from the same process. The cost is overhead: every thread creation, destruction, and context switch requires a system call and kernel data structures. On modern systems, this overhead is small enough that kernel threads are the dominant model. Linux, for example, implements threads as lightweight processes (via `clone()`) that share address space, making kernel thread operations fast enough for most applications.

The hybrid M:N model maps M user-level threads onto N kernel threads, trying to get the best of both worlds: fast user-space switching for threads that don't need parallelism, and kernel threads to provide actual parallel execution across cores. The user-space scheduler multiplexes many user threads onto fewer kernel threads. When a user thread blocks, the scheduler can swap in another user thread on the same kernel thread. In theory, this is ideal. In practice, M:N threading is complex to implement correctly — the user scheduler and kernel scheduler can make conflicting decisions, leading to priority inversion and subtle bugs. Most modern systems have abandoned M:N models in favor of 1:1 (one user thread per kernel thread), accepting the modest kernel overhead in exchange for simplicity and predictability. Go's goroutine scheduler is a notable modern exception that successfully implements an M:N-like approach.

Practice Questions 5 questions

Prerequisite Chain

Understanding Zero → The Number Zero → Counting to Five → Counting to 10 → Counting to 20 → Counting a Set of Objects Up to 20 → Cardinality: The Last Number Counted → Matching Numerals to Quantities → Subitizing Small Quantities → Addition Within 10 → Number Bonds to 10 → Addition Within 20 → Doubles and Near Doubles → Doubles Facts Within 10 → Near Doubles Facts Within 20 → Mental Math Strategies for Addition → Mental Math: Adding and Subtracting Tens → Addition Within 100 → Repeated Addition as Multiplication → Multiplication as Equal Groups → Multiplication: Arrays → Basic Multiplication Facts (0s, 1s, 2s, 5s, 10s) → Multiplication Facts Within 100 → Division as Equal Sharing → Division as Grouping (Measurement Division) → Division: Grouping (Repeated Subtraction) Model → Division: Fair Sharing Model → Division as Equal Sharing → Division as Grouping → Basic Division Facts → Division Facts Within 100 → Multiplication and Division Fact Families → Relationship Between Multiplication and Division → Division Facts as Inverse of Multiplication → Remainders and Quotients in Division → Division Word Problems → Multi-Step Word Problems → Solving Multi-Step Word Problems → Multiplication Word Problems → Division Word Problems → Introduction to Long Division → Factors and Multiples → Prime and Composite Numbers → Equivalent Fractions → Relating Fractions and Decimals → Decimal Place Value → Integers and the Number Line → Comparing and Ordering Integers → Absolute Value → Adding Integers → Subtracting Integers → Multiplying Integers → Introduction to Exponents → Order of Operations → Integer Order of Operations → Variable Expressions → The Distributive Property → Variables and Expressions Review → Introduction to Polynomials → Adding and Subtracting Polynomials → Multiplying Polynomials → Factorial → Permutations → Combinations → Counting Principles: Addition and Multiplication Rules → Introduction to Graph Theory → Propositional Logic Foundations → Logical Equivalences → Boolean Algebra → Boolean Type and Truth Values → Comparison Operators and Boolean Tests → Logical Operators and Boolean Algebra → Boolean Algebra and Fundamental Laws → Logic Gates Fundamentals → Implementing Boolean Functions with Gates → Karnaugh Map Simplification → Combinational Circuit Design → Flip-Flops and Latches → Binary Counters: Design and Analysis → Binary Arithmetic → Fixed-Point Number Representation → Two's Complement Representation → Overflow and Underflow Detection → Binary Adders: Half-Adders and Full-Adders → Full Adder and Carry Propagation → Carry Lookahead Adder Design → Half Adder Circuit Design → Multiplication Circuit Design → Sequential Circuit Design → Registers and Register Files → Instruction Set Architecture (ISA) → Kernel Architecture and OS Structure → System Calls and User/Kernel Mode → Processes and the Process Control Block → Thread Models: User-Level and Kernel Threads

Longest path: 95 steps · 356 total prerequisite topics

Prerequisites (1)

Leads To (1)