Linux核心開發 — 進程式控制制,linux核心開發進程
本章主要是以代碼的角度分析進程的定義、狀態、資料結構等概念。
進程的定義
進程是一段啟動並執行程式,他是一個動態可執行實體。而程式是代碼和資料的集合,代碼是一個靜態實體,程式是可以供多個進程使用,比如相同的應用程式可以在不同的電腦上運行而產生多個進程。
進程四要素
進程四要素主要是針對代碼中對線程、進程的區別而言:
l 有一段程式供其執行
l 有進程專用的核心堆棧空間
l 有核心控制塊(有一個task_struct 資料結構),擁有核心控制塊,才能被核心調度
l 有獨立的使用者空間
如何進程、使用者線程、核心線程:
進程的狀態
1)#defineTASK_RUNNING 0
正在被CPU執行,或者已經就緒,隨時可以執行。進程剛建立就處於這種狀態下。
2)#defineTASK_INTERRUPTIBLE 1
處於等待中的進程,待等待條件為真時被喚醒,也可以由訊號過著中斷喚醒。
3)#defineTASK_UNINTERRUPTIBLE 2
處於等待中的進程,待資源有效時背喚醒,但是不可以被其他進程的訊號或者中斷喚醒。
4)#define__TASK_STOPPED 4
進程中止執行。當接收到SIGSTOP或者SIGTSTP訊號時進入此狀態,知道接收到SIGCONT訊號後,進程重新回到 TASK_RUNNING狀態。
5)#define__TASK_TRACED 8
處於調試狀態的進程
6) #defineEXIT_ZOMBIE 16
表示進程已經終止執行,但是父進程尚未通過waitpid()收集進程死亡的相關資訊。
7) #defineEXIT_DEAD 32
進程終止的最終狀態,父進程已經收集完進程死亡相關資訊,此進程將被系統刪除。
8) #defineTASK_DEAD 64
進程退出是處於此狀態(EXIT_DEAD和EXIT_ZOMBIE由單獨的變數來記錄,是對TASK_DEAD的細分)。
9) #defineTASK_WAKEKILL 128
類似於TASK_UNINTERRUPTIBLE,Linux 2.6.25 核心新增的狀態,可被致命訊號(SIGKILL)喚醒。
#define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
#define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED)
#define TASK_TRACED (TASK_WAKEKILL | __TASK_TRACED)
#define TASK_NORMAL (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE)
進程的資料結構
在Linux 中進程、線程都採用task_struct資料結構進行描述,下面將講訴最主要的幾個資料結構成員的用途。
volatile long state; //進程狀態
unsigned int flags; //進程描述相關標誌
int prio, static_prio, normal_prio; //進程優先順序,數值越大,優先順序越小
unsigned int rt_priority; //進程運行優先順序
unsigned int policy; //進程調度策略
int exit_state; //進程退出時的狀態
struct mm_struct *mm; //進程記憶體管理資訊
pid_t pid;//進程號
資料結構與核心堆棧空間
Linux的核心堆棧只有兩個頁面大小(8K),在2.4的核心中,task_struct是被放在核心堆棧的底部。
然而在2.6的版本調整了資料結構的佔用儲存空間的方式,核心堆棧底部只放一個thread_info_structure的資料結構,此結構描述了task_struct所在的位置。
Linux核心中有一個current的指標,總是指向正在執行的task_struct。
linux核心怎對進程分類
可以吧,
linux核心的三種調度方法:
1,SCHED_OTHER 分時調度策略,
2,SCHED_FIFO即時調度策略,先到先服務
3,SCHED_RR即時調度策略,時間片輪轉
即時進程將得到優先調用,即時進程根據即時優先順序決定調度權值,分時進程則通過nice和counter值決定權值,nice越小,counter越大,被調度的機率越大,也就是曾經使用了cpu最少的進程將會得到優先調度。
SHCED_RR和SCHED_FIFO的不同:
當採用SHCED_RR策略的進程的時間片用完,系統將重新分配時間片,共置於就緒隊列尾。放在隊列尾保證了所有具有相同優先順序的RR任務的調度公平。
SCHED_FIFO一旦佔用cpu則一直運行。一直運行直到有更高優先順序任務到達或自己放棄。
如果有相同優先順序的即時進程(根據優先順序計算的調度權值是一樣的)已經準備好,FIFO時必須等待該進程主動放棄後才可以運行這個優先順序相同的任務。而RR可以讓每個任務都執行一段時間。
相同點:
RR和FIFO都只用於即時任務。
建立時優先順序大於0(1-99)。
按照可搶佔優先順序調度演算法進行。
就緒態的即時任務立即搶佔非即時任務。
請參考
Linux核心中進程0的主要任務是什?
總結一下有如下幾個要點:
1. 進程0是所有其他進程的祖先, 也稱作idle進程或swapper進程.
2. 進程0是在系統初始化時由kernel自身從無到有建立.
3. 進程0的資料成員大部分是靜態定義的,即由預先定義好的INIT_TASK, INIT_MM等宏初始化.
進程0的描述符init_task定義在arch/arm/kernel/init_task.c,由INIT_TASK宏初始化。 init_mm等結構體定義在include/linux/init_task.h內,為init_task成員的初始值,分別由對應的初始化宏如INIT_MM等初始化
Process 1
進程0最終會通過調用kernel_thread建立一個核心線程去執行init函數,這個新建立的核心線程即Process 1(這時還是共用著核心線程0的資源屬性如地址空間等)。init函數繼續完成剩餘的核心初始化,並在函數的最後調用execve系統調用裝入使用者空間的可執行程式/sbin/init,這時進程1就擁有了自己的屬性資源,成為一個普通進程(init進程)。至此,核心初始化和啟動過程結束。下面就進入了使用者空間的初始化,最後運行shell登陸介面。(註:Init進程一直存活,因為它建立和監控在作業系統外層執行的所有進程的活動。)
——————
這段對進程0的描述引用自《Understanding The Linux Kernel - Third Edtion》
The ancestor of all processes, called process 0, the idle process, or, for historical reasons, the swapper process, is a kernel thread created from scratch during the initialization phase of Linux. This ancestor process uses the following statically allocated data structures (data structures for all other processes are dynamically allocated)