📖 推薦閱讀:《Yocto項目實戰教程:高效定制嵌入式Linux系統》
🎥 更多學習視頻請關注 B 站:嵌入式Jerry
Linux 任務調度在進程管理中的關系和運行機制
Linux 內核中的“任務調度”是進程管理系統的核心部分,相互關聯而且分工明確。本文通過概念分析、模型分布、行為模式、調度策略、管理工具、代碼示例和流程總結,全面講解 Linux 任務調度在進程管理中的作用和機制。
一、任務 vs 進程:基本概念分清
概念 | 含義 |
---|---|
進程 (Process) | 抽象的運行單元,擁有獨立的虛擬地址空間和資源 |
線程 (Thread) | 進程內部的執行流 |
任務 (Task) | Linux 內核中對進程和線程的通用統一概念,對應一個 task_struct 結構,是調度的基本單元 |
同一進程內的多個線程,將在內核中分別代表為多個 task
二、調度系統結構與模式
Linux 調度系統分為以下幾個層級:
1. 調度器(Scheduler)
- 核心模塊,管理所有任務的調度邏輯。
- 入口函數如
schedule()
、pick_next_task()
、context_switch()
。
2. 調度行為(Scheduling Behavior)
定義內核是否允許任務在運行中被中斷(即“搶占”)。
模式 | 名稱 | 說明 |
---|---|---|
搶占式 | Preemptive | 當前任務可以隨時被更高優先級任務搶占 CPU,適合響應敏感系統(Linux 默認支持) |
非搶占式 | Non-preemptive | 當前任務必須主動放棄 CPU(如阻塞或退出),適合嵌入式、批處理任務等 |
注意:搶占式是一種調度行為,不是調度策略,它適用于不同調度策略下的調度邏輯實現。
3. 調度策略(Scheduling Policy)
調度器采用不同策略決定如何選擇任務。
策略 | 類型 | 搶占行為 | 說明 |
---|---|---|---|
SCHED_NORMAL (CFS) | 非實時 | 搶占式 | 默認策略,基于虛擬運行時間(vruntime)公平調度 |
SCHED_FIFO | 實時 | 非搶占式 | 先來先服務,不自動讓出 CPU,適合控制系統 |
SCHED_RR | 實時 | 搶占式 | 時間片輪轉,適合需要時間約束的實時任務 |
SCHED_DEADLINE | 實時 | 搶占式 | 基于截止時間和周期調度,用于軟/硬實時系統 |
三、任務調度流程:從狀態到切換
任務狀態:
狀態 | 說明 |
---|---|
TASK_RUNNING | 可調度,或正在運行 |
TASK_INTERRUPTIBLE | 等待被中斷喚醒 |
TASK_UNINTERRUPTIBLE | 不可被中斷,用于硬件阻塞操作 |
TASK_DEAD | 任務結束,正在回收資源 |
調度進程切換流程:
正在運行的任務 A||規則觸發 (CPU 用完 / 阻塞 / 有高優先級任務)|schedule()|pick_next_task()|context_switch(A, B)|
切換到 B 執行
四、調度管理工具
工具 | 功能 |
---|---|
ps / top / htop | 查看運行任務信息 |
chrt | 設置或查詢任務的調度策略(如 FIFO、RR) |
taskset | 設置 CPU 給任務的親和性(CPU affinity) |
schedtool | 更細化設置調度策略和優先級 |
/proc/[pid]/sched | 查看進程調度信息結構體 |
五、代碼實戰:兩個線程設置不同調度策略
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <unistd.h>void *low_task(void *) {while (1) {printf("low priority running\n");sleep(1);}
}void *high_task(void *) {while (1) {printf("HIGH priority running\n");sleep(1);}
}int main() {pthread_t t1, t2;struct sched_param param;pthread_create(&t1, NULL, low_task, NULL);pthread_create(&t2, NULL, high_task, NULL);param.sched_priority = 10; // lowpthread_setschedparam(t1, SCHED_RR, ¶m);param.sched_priority = 80; // highpthread_setschedparam(t2, SCHED_RR, ¶m);pthread_join(t1, NULL);pthread_join(t2, NULL);return 0;
}
通過
pthread_setschedparam
分別設置不同線程的調度策略與優先級,可觀察搶占調度行為,高優線程會頻繁搶占 CPU。
六、調度模型補充說明:是否還有其他調度模式?
除了搶占式與非搶占式,還有以下相關概念值得補充:
1. 自愿搶占(Voluntary Preemption)
- Linux 內核配置中
CONFIG_PREEMPT_VOLUNTARY
- 表示僅在特定調度點(如 IO 阻塞、顯式調用
schedule()
)才允許切換。 - 優點是可控性好,適合桌面/服務器系統,缺點是實時性較差。
2. 強制搶占(Fully Preemptible)
CONFIG_PREEMPT
- 表示內核大多數路徑都允許被搶占,適合響應及時性高的系統。
3. 實時搶占補丁(PREEMPT_RT)
- 加強版本的內核實時性特性,幾乎所有內核上下文都可被中斷。
- 適合工業級/控制系統等嚴格實時場景。
七、總結:調度機制是進程管理的動態執行核心
- ? 任務是調度的基本對象,所有進程/線程均由 task_struct 管理
- ? 調度行為定義是否可打斷當前任務(搶占與否)
- ? 調度策略定義如何選擇下一個任務(如 FIFO、RR、CFS)
- ? 調度器通過 schedule/pick/context_switch 完成任務切換
- ? 配套工具(如 chrt、schedtool)是日常開發/調試調度的關鍵武器
📖 推薦閱讀:《Yocto項目實戰教程:高效定制嵌入式Linux系統》
🎥 更多學習視頻請關注 B 站:嵌入式Jerry