程序排程實驗 程序執行及其排程

2021-10-12 08:49:47 字數 3019 閱讀 9919

程序概念從空間的維度上來看,程序是乙個由多種資訊構成的綜合體,它包括**段、資料段、堆、堆疊等,圖示如下:

綜合程序關聯的各種資訊而構成了的乙個資料結構,我們稱為程序控制塊(process control block,pcb ),也稱為任務控制塊(task control block),這些相關的資訊包括:

從時間的維度上來看,程序是乙個活動實體,表現在兩個方面:

其一,它牽連到cpu和記憶體,觸發cpu各種邏輯算術運算和記憶體中的資料活動,比如,磁碟上有乙個可執行二進位制檔案,雙擊它時,就會衍生出來乙個程序,雙擊它這一動作會觸發一系列連鎖反應,這包括程式載入到記憶體,通過pc逐個地引用程式指令到cpu內執行,資料在記憶體和暫存器之間傳輸等等。

其二,它的狀態是隨時間而變化的,且必須遵從乙個原則:一次只有乙個程序可在乙個處理器上執行,但是許多程序可處於就緒或等待狀態。如下是乙個程序狀態圖模型:

新的:程序正在建立。

就緒:程序等待分配處理器。

等待:程序等待發生某個事件(如i/o完成或收到訊號)。

執行:指令正在執行。

終止:程序已經完成執行。

程序排程

其中佇列頭head指向鍊錶的第乙個pcb塊,tail指向鍊錶的最後乙個pcb塊。

更進一步,建立起基於佇列圖的程序排程,其模型如下:

程序排程總是從就緒佇列裡選擇乙個在cpu中執行,程序在cpu中執行的活動可能是:

程序執行

程序建立形成程序樹,對於linux作業系統而言,系統初始化程序(其程序名稱可能為init,也可能為systemd,但是其id必定是為1)是該樹形結構的根,其它所有程序都能追溯到它為止,如下,是ubuntu linux系統的乙個程序樹片段:

從圖可以看出,該系統提供命令「pstree」列印系統當前的程序樹,每個新程序可以建立其他程序,並使用唯一的程序識別符號(pid)來標記,同時以此來引用該程序。

關於程序建立的實現,在《unix環境高階程式設計》一書中有非常詳細的介紹,這裡只給出fork()系統呼叫實現的乙個例項。

請看,該例項的程式設計模型如下:

第乙個維度是空間的維度,考慮子程序關聯的資訊內容是什麼及如何存放的問題,

note

顯而易見,以上三種實現對於記憶體空間的使用效率最高的是第三種,「寫時複製」技術是一種高效地利用資源的方式。

第二個維度是時間的維度,考慮子程序與父程序競爭處理器的使用權問題,即它們的執行時序問題。父程序建立了子程序,直觀的想象應當是父程序先執行,儘管父程序先於子程序誕生,但是,對於選用了「寫時複製」的技術而建立程序的方式,是子程序先執行,這主要是考慮到,通常,在子程序中,會通過exec系統呼叫載入新的**段,讓子程序先執行能避免「寫時複製」拷貝共享頁面的機會,當然,父子程序誰先執行取決於系統的排程策略。   

程序終止

脫離計算機系統範疇,我們可以把乙個程序認為就是乙個任務,在日常事務中,終止乙個任務的原因有很多,比如:

等等~。

總之,對於計算機系統,程序是具有生命週期的,可能被終止後就不復存在了,也可能又會被復生,這裡,我們考慮作業系統是如何管理程序終止問題。

作業系統提供系統呼叫exit()來終止程序,常規程式設計中,在main()函式的結束使用返回語句實際上也是呼叫了exit(),這裡不再詳述,基於上面給出的程式設計模型,我們進行編碼實驗,如下:

實驗一:不使用exec系統呼叫,觀察父子程序對相同變數的取值

#include #include #include #include int    globvar = 6;    /* external variable in initialized data */char  buf = "a write to stdout\n";intmain(void) else if (pid == 0)  else   printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar,    var);  exit(0);}
構建並執行程式

glob代表資料段,var代表堆疊段,在父子程序中,它們的值不相同,這說明,父子程序實際訪問的物理記憶體單元不一樣,儘管他們通過同乙個變數引用(也就是說使用了相同的虛擬位址),當然,父子程序至少共用了同一段**即第30行**。

實驗二:使用exec系統呼叫,觀察程序從建立到終止的過程

#include #include #include int main()  else if (pid == 0)   else     return 0;}
構建並執行程式

對照上面所述的程式設計模型,**行22先執行,然後執行**行17,fork()系統呼叫返回值為0標記在子程序空間,大於0標記在父程序空間,fork()之初,在子程序空間的**是完全和父程序相同,之後,在父程序空間中,使用wait()系統呼叫控制自己的狀態進入等待子程序終止訊號,父程序讓出處理器,在子程序空間中,使用execlp()載入並執行程式ls,子程序一旦終止,就會觸發父程序回到執行狀態,從而執行**行24。

實驗三程序排程

1.1.實驗目的 用高階語言完成乙個程序排程程式,以加深對程序的概念及程序排程演算法的理解。1.2.實驗要求 1.2.1例題 設計乙個有 n個程序併發執行的程序排程模擬程式。程序排程演算法 採用最高優先順序優先的排程演算法 即把處理機分配給優先順序最高的程序 和先來先服務 若優先順序相同 演算法。1...

程序排程演算法(程序排程策略)

程序排程演算法 排程演算法是指 根據系統的資源分配策略所規定的資源分配演算法。一 先來先服務和短作業 程序 優先排程演算法 1.先來先服務排程演算法。先來先服務 fcfs 排程演算法是一種最簡單的排程演算法,該演算法既可用於作業排程,也可用於程序排程。fcfs演算法比較有利於長作業 程序 而不利於短...

程序排程三 程序排程介紹

一 程序排程介紹 1 程序排程的產生 程序從使用資源方面可以分為如下兩類,不管是i o還是cpu受限類的程序,cpu都希望再盡可能短的時間 完成更多的工作,但另一方面,又希望盡可能的減少資源 i o或cpu 的消耗,這兩則之間存在矛盾,所以程序 的排程管理就是來協調兩者之間的衝突。型別別稱 描述示例...