程序控制相關的標頭檔案一般都是
程序建立簡單的來說就是建立乙個pcb。使用 fork 庫函式。
pid_t fork()
;pid_f vfork
(void
);
fork — 通過複製呼叫程序也就是父程序的pcb來建立乙個新的子程序。fork的返回值是:父程序返回子程序的pid,子程序返回0,若建立失敗返回-1.
vfork — 建立子程序,父子程序公用乙個虛擬位址空間。
父子程序公用乙個虛擬位址空間的作用是為了防止呼叫棧混亂,具體實現是:使父程序呼叫vfork之後就一直阻塞,一直阻塞到子程序退出 或者 子程序發生程式替換。返回值和fork一樣。
vfork建立的子程序不能用return退出,只能用exit。
因為fork加入了寫時拷貝技術之後,vfork建立子程序的高效率的地位被取代,vfork也就慢慢被淘汰。寫時拷貝技術提高子程序的效率,避免了無謂的開闢空間。
fork 和 vfork再核心中建立程序都是呼叫 clone函式實現pcb建立並拷貝資料。
fork 呼叫失敗的原因:
1. 系統中存在太多的程序;
2. 實際使用者程序數超過了限制。
通常使用fork建立子程序之後,可以通過返回值的不同使用if分流,分辨出父子程序。
程序終止
程序終止就是退出程序,程序退出分為兩種:1.正常退出,結果符合或者不符合預期退出;2.異常退出:常見的異常退出就是程式奔潰。
關於程序退出的方法:
main 函式中的return;
兩種exit函式,通常使用的都是庫函式中的exit(), 另乙個是系統呼叫介面中的_exit();
異常退出:linux下使用ctrl + c,訊號終止。
void
exit
(int status)
;//庫函式中的exit
//status是程序終止狀態,父程序通過wait來獲取該值
return 和 exit() 兩種方式都會在退出之前重新整理緩衝區,return 通常在main中退出程序,而exit可以在任意地方使用。
void
_exit
(int status)
;//系統呼叫介面中的exit
_exit 在退出之前不會重新整理緩衝區,直接就釋放全部資源,緩衝區的資料會被丟棄。
庫函式是系統呼叫介面的一層封裝,所以可以理解,exit函式底層其實也呼叫了_exit函式,但是在呼叫之前做了清理工作和緩衝區資料寫入工作。
程序等待就是等待子程序退出或者狀態改變,獲取子程序的退出返回值,並且釋放子程序的資源,防止殭屍程序產生。
標頭檔案包含
有兩種等待的介面:
pid_t wait
(int
* status)
;//等待任意乙個子程序退出
//status中儲存的是子程序退出的返回值
//返回值:成功返回子程序的pid,失敗返回-1
pid_t waitpid
(pid_t pid,
int* status,
int options)
;//等待指定程序或者任意程序退出
//pid指定子程序的pid status 子程序退出的返回值 options選項標誌
//如果引數中的pid>0 就是指定程序, pid==-1表示任意乙個子程序
//返回值:-1 表示出錯 0 表示沒有子程序退出 >0表示退出子程序的pid
status記憶體中,高16位沒有使用,低16位的高8位儲存子程序的返回值,低8位中的高1位儲存core dump標誌,低7位表示異常訊號值。所以,若低7位中異常訊號為0表示程式正常退出,否則異常退出,異常退出時的返回值不具備任何意義。
兩個介面的不同:
wait:一直阻塞的等待任意乙個子程序退出,子程序退出之後,獲取返回值,放入status中,返回退出子程序的pid。
waitpid:一直阻塞等待任意乙個或者指定子程序退出,返回退出子程序的pid。
如果子程序一直沒有被退出,wait將一直阻塞。如果子程序已經退出,呼叫這兩個函式的時候,會立即返回,並且釋放資源。如果不存在該子程序,則立即報錯返回。
阻塞和非阻塞:
阻塞:為了完成乙個功能發起呼叫,若當前不具備完成條件,則等待直到條件具備完成功能後返回。
非阻塞:為了完成乙個功能發起呼叫,若當前不具備完成條件,則立即報錯返回。
(通常非阻塞需要迴圈操作,隔段時間過來檢視是否具備完成條件)
extern
char
** environ;
//1.
intexecl
(const
char
* path,
const
char
* arg,..
.)//使用path這個路徑的程式,替換當前程序要執行的程式。引數數量不定以 null 結束。
//arg是函式執行引數,ar**是陣列形式儲存執行引數,envp環境變數列表
//2.
intexeclp
(const
char
* file,
const
char
* arg,..
.)//使用file這個檔案的程式,替換當前程序要執行的程式。引數數量不定以 null 結束
//3.
intexecle
(const
char
* path,
const
char
* arg,..
.,char
*const envp)
//4.
intexecv
(const
char
* path,
char
*const ar**)
//5.
intexecvp
(const
char
* file,
char
*const ar**)
//6.
intexecvpe
(const
char
* file,
char
*const ar**,
char
*const envp)
//7.這是系統呼叫介面
intexecve
(const
char
* path,
char
*const ar**,
char
*const envp[
])
其中execve是系統呼叫介面,其他介面都是庫函式,底層呼叫execve介面。
這些函式如果呼叫成功則載入新的程式從啟動**開始執行,不再返回;
如果呼叫出錯則返回 -1; 所以exec函式只有出錯的返回值,沒有成功的返回值。
linux 程序控制
什麼是程序 每乙個程序在系統中都有唯一的id標示它,此id為程序標示符 程序標示符的型別 pit t,其實是乙個無符號整形 乙個程序標示符對應唯一的乙個程序,多個程序標示符可以對應同乙個程式 程序和程式的區別 程式 可執行的二進位制 檔案,這種檔案載入到記憶體中執行就得到了乙個程序 程序 同乙個程式...
Linux程序控制
linux程序控制 獲取pid include include pid t getpdi void 獲取本程序id pdi t getppid vodi 獲取父程序id,及獲取建立子程序的程序id 程序建立 include pid t fork void 建立子程序 呼叫一次返回兩次值 1.父程序中...
linux程序控制
linux程序控制 編寫命令直譯器 一 背景 之前在 計算機作業系統 這本書中已經多次接觸了程序這一概念,而程序在作業系統中具體是做什麼的呢?卻沒有實際的與程序發生過互動,因此也就沒有實際的感受。對於我來說程序僅僅停留在概念的層面上 程序是程式執行時的記憶體空間和設定或者說程序就是程式的進行時。沒有...