許多作業系統都提供了產生(spawn)程序的機制,首先在新的位址空間裡建立程序,讀入可執行檔案,最後開始執行。
unix採用了與眾不同的實現方式,它把上述步驟分解到兩個單獨的函式中去執行:fork()和exec()。
把這兩個函式組合起來使用和其他系統使用的單一函式效果相似。
(1)寫時拷貝
傳統的fork()會直接把所有的資源直接複製給新程序。這種實現過於簡單並且效率低下,因為拷貝的資料可能不共享,並且大多數情況下新程序都是執行exec(),那麼拷貝過來也毫無意義。
寫時拷貝技術是一種可以推遲甚至免除拷貝資料的技術。核心並不複製整個程序位址空間,而是讓父子程序共享同乙個拷貝。只有在需要寫入的時候才進行,此前都是以唯讀方式共享。
fork()的實際開銷就是複製父程序的頁表(作業系統為每乙個程序維護了乙個頁表)以及給子程序建立唯一的程序描述符。
(2)fork()
函式原型:
#includepid_t fork(void);
返回值:子程序返回0,父程序返回子程序id,出錯返回-1
由fork建立的新程序被成為子程序。fork函式被呼叫一次,但返回兩次。兩次的唯一區別是子程序的返回值是0,而父程序的返回值則是子程序的程序id。
fork()函式的核心實現原理:
clone()系統呼叫通過一系列的引數標誌來指明父子程序需要共享的資源。fork()、vfork()和_clone()庫函式都根據各自需要的引數標誌呼叫clone(),然後clone()去呼叫do_fork()。
do_fork()的定義在kernel/fork.c檔案中,該函式呼叫copy_process()函式,然後讓程序開始執行。copy_process()函式完成的工作如下:
1)呼叫dup_task_struct()為新程序建立乙個核心棧、thread_info結構和task_struct,這些值與當前程序的值相同。此時,父子程序的描述符是完全相同的。
2)檢查並確保新建立這個子程序後,當前使用者所擁有的程序數目沒有超出給它分配的資源的限制。
3)子程序著手使自己與父程序區別開來。程序描述符內許多成員都要被清0或者設為初始值。一些不是繼承而來的描述符成員,主要是統計資訊。task_struct中大多數資料依舊未被修改。
4)子程序狀態被設定為task_uninterruptible(不可中斷),以保證不會投入執行。
5)copy_process()呼叫copy_flags()以更新task_struct的flags成員。表明程序是否擁有超級使用者許可權的pf_superpriv標誌被清0。表明程序還沒有呼叫exec()函式的pf_forknoexec標誌被設定。
6)呼叫alloc_pid()為新程序分配乙個有效的pid。
7)根據傳遞給clone()的引數標誌。copy_process()拷貝或共享開啟的檔案、檔案系統資訊、訊號處理函式、程序位址空間和命名空間等。一般情況下,這些資源會被給定程序的所有執行緒共享;否則這些資源對每個程序是不同的,因此拷貝到這裡。
8)最後copy_process()做掃尾工作並返回乙個指向子程序的指標。在到do_fork()函式,如果copy_process()函式成功返回新建立的子程序被喚醒並讓其投入執行。
(3)vfork()
函式原型:
pid_t vfork(void);
除不拷貝父程序的頁表項外,vfork()與fork()功能相同。子程序作為父程序的乙個單獨的執行緒在它的位址空間執行,父程序被阻塞,直到子程序退出或執行exec()。子程序不能向位址空間寫入。
1)在呼叫copy_process()時,task_struct的vfork_done成員會被設定為null。
2)在執行do_fork()時,如果給定特別標誌,則vfork_done會指向乙個特定位址。
3)子程序先開始執行後,父程序不是馬上恢復執行,而是一直等待,直到子程序通過vfok_done指標向它傳送訊號。
4)在呼叫mm_release()時,該函式用於程序退出記憶體位址空間,並檢查vfork_done是否為空,若果不為空,則向父程序傳送訊號。
5)回到do_fork(),父程序醒來並返回。執行成功,子程序在新的位址空間裡執行而父程序也恢復在原位址空間的執行。
程序管理 一 程序的概念以及程序的建立
程式一旦跑起來就是乙個程序,程序是乙個可以執行的例項。每個程序都擁有乙個自己的虛擬cpu,但是實際上只有乙個cpu,其只是在各個程序之間快速的切換,這種快速切換就叫做多道程式設計 例子 乙個計算機科學家給女兒做蛋糕,他有做蛋糕用的食譜,廚房中有大量的原料,比如香草 雞蛋 麵粉 糖等等。其中食譜就是程...
程序建立,程序等待,程序終止
1 程序建立,2 程序等待,3 程序終止 程序建立被定義為通過父程序建立子程序的過程。fork函式 函式原型 pid t fork void 特點 1.fork函式呼叫一次,返回兩次兩次返回值得區別分別是子程序當中的返回值為0,父程序當中的返回值為新建子程序的id 將id返回給父程序的原因是沒有函式...
OS複習 程序管理3
根據執行程序的處理機是由程序自己釋放,還是被強行剝奪,可以將程序排程方式分為非剝奪方式和剝奪方式兩種。執行程序只有在執行完畢,或因申請i o阻塞自己時,才中斷其執行,釋放處理機,排程新的程序執行。這種方式不利於 即時性 要求較高的分時和實時系統,主要用於批處理系統。不能強行剝奪 作業系統可以在新程序...