🎯 Introduction
During our recent Embedded Linux Overview Webinar for one of the world’s top semiconductor companies, a powerful question came up:
“How does the Linux kernel schedule threads, especially inside multi-threaded applications?”
This is a fundamental concept every Embedded Linux professional should understand.
In this blog, we will explore exactly how Linux treats processes and threads, how the Completely Fair Scheduler (CFS) assigns CPU time, and how group scheduling prevents multi-threaded programs from dominating the system.
Let’s decode how Linux manages fairness, performance and responsiveness — all through a beautifully unified design.
🧩 1. The Unified Task Model — Processes and Threads Are the Same
In Linux, the boundary between processes and threads is surprisingly thin.
The kernel models both as tasks, represented by the same structure:
struct task_struct
This is why Linux often describes both entities simply as tasks.
➤ Process Creation
When a new process is created using fork():
- A new task_struct is created
- A new virtual memory space is allocated
- The new process runs independently
➤ Thread Creation
When a thread is created using pthread_create():
- Behind the scenes, it uses the
clone()system call - The kernel still creates a new task_struct
- But this new task shares memory and resources with the parent
➤ Scheduler Perspective
To the scheduler:
- A thread is a task
- A process is a task
- Everything runnable is simply… a task
The scheduler does not care whether a task belongs to a multi-threaded app or stands alone.
This is the foundation of Linux scheduling.
⚙️ 2. The Completely Fair Scheduler (CFS)
Most Linux systems use the CFS scheduler for normal tasks (SCHED_OTHER / SCHED_NORMAL).
Its goal: ensure everyone gets a fair share of CPU time.
🔸 Virtual Runtime (vruntime)
Instead of traditional priority queues, CFS tracks a task’s “fairness” using vruntime — the amount of time a task has been allowed to run.
- A task with lower vruntime runs next
- CPU-bound tasks accumulate vruntime faster
- Interactive tasks accumulate slower and get preference
🔸 Interactive Bias
If a task sleeps often (e.g., waiting for input), CFS rewards it by slowing its vruntime growth.
This keeps your system snappy and responsive.
🧿 3. Group Scheduling — Preventing Thread Abuse
Here’s a classic fairness problem:
If a process spawns 10 threads, should it get 10× more CPU time than a single-threaded process?
Without safeguards — yes, it would.
Linux solves this using autogrouping, also known as group scheduling.
🔹 The Fairness Problem
Since each thread is its own task, a multi-threaded process could unfairly dominate the CPU.
🔹 The Linux Solution
Linux groups all threads of one process together.
🔹 How It Works
- CFS allocates CPU time to groups first
- Each group gets an equal share
- Then the group’s share is divided among its threads
For example:
| Process | Threads | CPU Share |
|---|---|---|
| Process A | 10 | 50% split among 10 threads |
| Process B | 1 | 50% given to 1 single thread |
This ensures fairness at the process level, not the thread level.
This design is one of the reasons Linux performs so predictably across heavy workloads.
⏱️ 4. Real-Time Scheduling (When Timing Must Be Precise)
Linux also supports real-time policies for time-critical work:
🔸 SCHED_FIFO and SCHED_RR
- Use fixed priorities (1–99)
- Always preempt normal CFS tasks
- Ideal for deterministic timing
🔸 Priority Inheritance
To prevent priority inversion when locking occurs, Linux supports priority inheritance, ensuring real-time threads are not starved.
This makes Linux suitable for real-time and embedded applications.
📌 Summary — How Linux Schedules Threads
Linux thread scheduling is built on four powerful principles:
- Unified Task Model:
Processes and threads are both tasks (task_struct). - CFS for Fairness:
Tracks runtime using vruntime to keep interactive tasks responsive. - Group Scheduling:
Prevents multi-threaded processes from hogging the CPU. - Real-Time Policies:
Handles time-critical workloads using priority-driven, deterministic scheduling.
This combination allows Linux to run everything from mobile apps to hard real-time embedded devices.
🚀 Master Linux Internals the Right Way
If you want to go deep into:
- Linux Fundamentals
- Application Development
- Device Drivers
- Kernel Internals
…then Linux Rapid Mastery is the perfect launchpad for you.
It includes:
✔ Weekly LIVE meetups
✔ Doubt-clearing sessions
✔ Assignment reviews
✔ Career guidance
✔ Structured step-by-step learning
👉 Join here: https://embitude.in/lrm
And become part of our community of Embedded Linux professionals:
👉 https://embitudeinfotech.graphy.com/s/community