程序概念從空間的維度上來看,程序是乙個由多種資訊構成的綜合體,它包括**段、資料段、堆、堆疊等,圖示如下:
綜合程序關聯的各種資訊而構成了的乙個資料結構,我們稱為程序控制塊(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 的消耗,這兩則之間存在矛盾,所以程序 的排程管理就是來協調兩者之間的衝突。型別別稱 描述示例...