1、前言
本文主要基于Linux Kernel 2.6.32 的源碼,對Linux的程序模型進行分析,大緻可以概括為如下内容:
1.前言
2.程序介紹
3.作業系統如何組織程序
4.程序狀态的轉化
5.程序的排程
6.參考資料
2、程序介紹
2.1 程序的概念
程序(Process)是計算機中的程式關于某資料集合上的一次運作活動,是系統進行資源配置設定和排程的基本機關,是作業系統結構的基礎。在早期面向程序設計的計算機結構中,程序是程式的基本執行實體;在當代面向線程設計的計算機結構中,程序是線程的容器。程式是指令、資料及其組織形式的描述,程序是程式的實體。
2.2 程序的檢視
2.2.1 Windows檢視程序
在Windows系統下可用CTRL+ALT+DEL組合鍵打開任務管理器對程序進行檢視:

2.2.2 Linux下檢視程序
Linux下可以在終端用ps指令來檢視程序:
3、作業系統如何組織程序
3.1 程序控制塊(PCB)
Linux系統中主要的活動實體就是程序。
每個程序執行一段獨立的程式并且在程序初始化的時候擁有一個獨立的控制線程。換句話說,每一個程序都擁有一個獨立的程式計數器,用這個這個程式計數器可以追蹤下一條将要被執行的指令。
所有的程序都被放在一個叫做程序控制塊(PCB),的資料結構中,可以了解為程序屬性的集合,該控制塊由作業系統建立和管理。每個程序在核心中都有一個程序控制塊來維護程序相關的資訊,Linux核心的程序控制塊是(task_struct)結構體。Linux通過task_struct(PCB)結構體來描述一個程序的所有資訊,結構體被定義在include/linux/sched.h
中。
程序建立時,作業系統就建立一個PCB結構,它之後就常駐記憶體,任一時刻可以存取, 在程序結束時删除。PCB是程序實體的一部分,作業系統通過PCB表來管理和控制程序,是程序存在的唯一标志。
3.2 程序辨別符(PID)
程序辨別符在task_struct結構體下定義:
pid_t pid; //核心中用以辨別程序的id
pid_t tgid; //用來實作線程機制
struct pid
{
atomic_t count;
unsigned int level;
/* lists of tasks that use this pid */
struct hlist_head tasks[PIDTYPE_MAX];
struct rcu_head rcu;
struct upid numbers[1];
};
每個程序都有一個唯一的辨別符(PID),核心通過這個辨別符來識别不同的程序,同時,程序辨別符(PID)也是核心提供給使用者程式的接口,使用者程式通過PID對程序發号施令。PID是32位的無符号整數,它被順序編号:新建立程序的PID通常是前一個程序的PID加1。然而,為了與16位硬體平台的傳統Linux系統保持相容,在Linux上允許的最大PID号是32767,當核心在系統中建立第32768個程序時,就必須重新開始使用已閑置的PID号。在64位系統中,PID可擴充到4194303。
4、程序狀态的轉化
4.1 三态模型
一個程序從建立而産生至撤銷而消亡的整個生命周期,可以用一組狀态加以刻劃,根據三态模型,程序的生命周期可分為如下三種程序狀态:
1. 運作态(running):占有處理器正在運作
2. 就緒态(ready):具備運作條件,等待系統配置設定處理器以便運作
3. 等待态(blocked):不具備運作條件,正在等待某個事件的完成
4.2 五态模型
在一個實際的系統裡程序的狀态及其轉換比上節叙述的會複雜一些,例如引入專門的建立态(new)和終止态(exit )
狀态轉換圖如下所示:
5、程序的排程
5.1 linux排程器的演變
目前的核心支援兩種排程器類(sched_setscheduler系統調用可修改程序的政策):CFS(公平)、RT(實時);5種排程政策:SCHED_NORAML(最常見的政策)、SCHED_BATCH(除了不能搶占外與正常任務一樣,允許任務運作更長時間,更好地使用高速緩存,适合于成批處理的工作)、SCHED_IDLE(它甚至比nice 19還有弱,為了避免優先級反轉使用)和SCHED_RR(循環排程,擁有時間片,結束後放在隊列末)、SCHED_FIFO(沒有時間片,可以運作任意長的時間);其中前面三種政策使用的是cfs排程器類,後面兩種使用rt排程器類。
5.2 CFS排程器的結構
第一個是排程實體sched_entity,它代表一個排程機關,在組排程關閉的時候可以把他等同為程序。每一個task_struct中都有一個sched_entity,程序的vruntime和權重都儲存在這個結構中。那麼所有的sched_entity怎麼組織在一起呢?紅黑樹。所有的sched_entity以vruntime為key(實際上是以vruntime-min_vruntime為機關,難道是防止溢出?反正結果是一樣的)插入到紅黑樹中,同時緩存樹的最左側 節點,也就是vruntime最小的節點,這樣可以迅速選中vruntime最小的程序。注意隻有等待CPU的就緒态程序在這棵樹上,睡眠程序和正在運作的程序都不在樹上。如下圖(來源見參考資料):
6、參考資料
1. https://baike.baidu.com/item/%E8%BF%9B%E7%A8%8B/382503?fr=aladdin
2. https://baike.baidu.com/item/%E8%B0%83%E5%BA%A6%E7%AE%97%E6%B3%95/3017645?fr=aladdin
3. https://www.cnblogs.com/puputongtong/p/5451210.html
4. https://blog.csdn.net/gatieme/article/details/52067518
轉載于:https://www.cnblogs.com/yukch3/p/8977948.html