《深入linux核心架構》C2 程序管理與排程

2021-09-24 11:32:11 字數 3195 閱讀 7121

現代作業系統(linux、windows)基本都能處理多項任務(多工系統),因而,此多工的管理和排程是核心的基本功能,第二章就圍繞此主體展開。相關主題如下:

linux支援實時程序和非實時程序(普通程序)。一般的程序都是普通程序,而實時程序強調希望得到系統的快速響應與處理,因而有較高的優先順序。應用程式可以通過nice系統呼叫修改程式的優先順序

#include int nice(int inc);
程序的生命週期大體可分為:執行、等待、睡眠等階段

,在核心中使用程序狀態表示:

r (task_running):可執行狀態&執行狀態(在run_queue佇列裡的狀態);

s (task_interruptible):可中斷的睡眠狀態,可處理signal;

d (task_uninterruptible):不可中斷的睡眠狀態,可處理signal,有延遲,不能有外部訊號喚醒,只能由核心親自喚醒;

t (task_stopped or task_traced):暫停狀態或跟蹤狀態,不可處理signal,因為根本沒有時間片執行**;

z (task_dead - exit_zombie):退出狀態,程序成為殭屍程序。不可被kill, 即不響應任務訊號, 無法用sigkill殺死.

以上狀態在核心中用各種巨集定義(sched.h)

,在除錯嵌入式程式時非常有用。如檢視系統mysqld守護程序的狀態

其外,文章介紹了linux的搶占式多工

處理:程序的兩種狀態選項:使用者態、核心態。核心態具有無限的權利,使用者態受到各種限制。使用者態切換到核心態的兩種方法:系統呼叫、中斷。系統呼叫是應用程式有意的,中斷是自動觸發的。

核心搶占:緊急情況下切換到另乙個程序,甚至當前是處於核心態執行系統呼叫(中斷不能被搶占)。

這裡要重點提下,現階段熱門的docker等虛擬性技術大多基於linux的命名空間(還一種技術是control group),其為應用程式提供源生態的核心虛擬化支援。

目前,核心支援6中命名空間:

uts:unix timesharing system;

ipc:程序間通訊;

mnt:檔案系統裝載;

pid:程序id管理;

user:使用者管理

net:網路命名空間。

命名空間為層級關係,父空間能檢視所有子空間的內容,反過來不行。

核心有一套完整的pid管理與分配方案,加入了pid 命名空間後,又存在全域性pid和區域性pid之分

,此部分相當複雜,建議深入閱讀分析,此處從簡。

使用者態程式可以使用fork、clone、vfork等系統呼叫產生新的程序/執行緒,然後使用exec函式族進行程序替換(elf檔案,替換原有程序的各個段)。

程序的排程啟用有兩種方式:週期性排程器

和主排程器

。其中,週期性排程器由系統時鐘中斷觸發,定期掃瞄排程佇列上是否有需要執行的程式;主排程器則採用schedule函式主動放棄當前程序的執行,使cpu選擇新的程序執行。

在排程順序上,所有可執行的程序按照時間在乙個紅黑樹中排序

,最左側的節點等待時間最長,最先被得到排程。紅黑樹是核心的一種標準資料結構,讀者可以在rbtree.c中檢視。

此外,核心採用模組化的設計分離排程器與排程類,排程器只負責選擇下乙個待執行的程序,而真正的程序管理功能由排程器類實現

。核心支援兩種排程器類(4.14原始碼中有5個排程器類):完全公平排程類、實時排程類。不同的排程類又有不同的排程策略,如下:

排程類 描述

對應排程策略

stop_sched_class

優先順序最高的執行緒,會中斷所有其他執行緒,且不會被其他任務打斷作用

1.發生在cpu_stop_cpu_callback 進行cpu之間任務migration

2.hotplug_cpu的情況下關閉任務

……dl_sched_class

採用edf最早截至時間優先演算法排程實時程序

……rt_sched_class

採用提供 roound-robin演算法或者fifo演算法排程實時程序,具體排程策略由程序的task_struct->policy指定

sched__rr:迴圈程序

sched_fifo:先進先出

fair_sched_clas

採用cfs演算法排程普通的非實時程序

sched_batch

sched_normal

idle_sched_class

……排程器類由sched_class表示,通過指標相互串聯。如:

const struct sched_class fair_sched_class =

isched = sched_getscheduler(0);

memset(&stsched, 0, sizeof(stsched));

sched_getparam(0, &stsched);

printf("after : %d, %d \n", isched, stsched.__sched_priority);

return error_success;

}程式首先通過sched_getscheduler獲取自身的排程策略;

之後,構建sched_param結構,通過sched_setscheduler修改自身的排程策略為fifo(實時程序),且優先順序為12;

最後,再次呼叫sched_getscheduler檢視自身的調查策略。

程序排程是os的基礎之基礎,本文只是通過書本講訴簡要的描述了排程的框架,可謂冰山一角。讀者若感興趣,可以閱讀核心相關原始碼。很多博主對此類主題也有深刻的解析,可以參閱,如:

linux程序排程器的設計--linux程序的管理與排程(十七)

感謝---完。

深入Linux核心架構筆記 程序管理與排程

概述 程序相關的基本概念 硬體實時程序有嚴格的時間限制,必須在可保證的時間範圍內得到處理,否則會有很嚴重的後果,請注意,這並不意味著所要求的時間範圍特別短,linux主流版本不支援硬實時處理 軟實時程序是硬實時程序的一種弱化形式,儘管仍然需要快速得到結果,但是稍微晚一點關係也不是很大,比如對cd機的...

深入Linux核心架構筆記 程序管理與排程2

程序表示 state 執行程序的狀態 task running 表示程序可以執行 task interruptiable 程序因為等待某種事件或者資源而睡眠,可以通過訊號喚醒 task uninterruptible 程序因為等待某種事件或者資源而睡眠,不能由訊號喚醒 task stopped 程序...

深入理解Linux核心 程序

1 程序的靜態特性 程序 程式執行時的乙個例項 程序描述符 task struct 程序的基本資訊 thread info 指向記憶體區描述符的指標 mm struct 程序相關的tty tty struct 當前目錄 fs struct 指向 檔案描述符的指標 files struct 所接收的訊...