一、函式wait
和waitpid
今天我們繼續通過昨天那個死爹死兒子的故事來講(
便於記憶
),現在看看
wait
和waitpid
函式。
#include
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid , int *statloc , int options); 若成功,返回程序
id,若出錯,返回0或
-1 wait系列函式的作用就是通知父親兒子的死訊的,父程序一般接收到
sigchld
訊號而呼叫
wait
,(等待終止),可能有三種情況發生:
(1).子程序都在
running
,則阻塞
(2).如果乙個子程序終止,則父程序獲取其終止狀態
(statloc
指標指向的空間
),然後立即返回
(3).如果它沒有任何子程序,則立即出錯返回
wait可以返回的四個終止狀態的互斥的巨集,分別為:
wifexited(status) 正常終止
wifsignaled(status) 異常終止
wifstopped(status) 暫停子程序
wifcontinued(status) 暫停後已經繼續的子程序
例子:
#include "apue.h"
#include void pr_exit(int status)
intmain(void)
waitpid函式,顧名思義,其作用就在於可以等待特定的
pid的子程序終止。此外,
waitpid
的options
引數提供了
wnohang
(相當於不阻塞的
wait
)、wcontinued
、wuntraced(
支援作業控制
)三個常量選項。
下面是乙個非常經典的fork
子、孫程序的示例:(兩次fork,有效的避免僵死程序)
#include "apue.h"
#include int
main(void)
else if (pid == 0)
if (waitpid(pid, null, 0) != pid) /* wait for first child */
err_sys("waitpid error");
/** we're the parent (the original process); we continue executing,
* knowing that we're not the parent of the second child.
*/sleep(30);
exit(0);
}
為了便於測試效果明顯,我將父程序sleep了30秒,然後退出,將孫程序sleep了60秒,然後退出。在這段**中,最先退出的是子程序,為了防止孫程序僵死,我們讓它sleep的時間更長,而父程序執行完畢退出後,孫程序被init程序收養,孫程序執行自己的任務,執行完畢後正常退出,使得該過程有效的避免了僵死程序。
此外,waitid
類似於waitpid
,但更為靈活,
wait3
、wait4
的附加引數可以返回所有子程序使用的資源概況,不在此詳細說明。
二、函式exec
當我們fork
乙個程序後,新的程序往往要呼叫
exec
執行乙個啟動例程,如第七章所述圖:
因此,呼叫exec
並不建立新的程序,只是用磁碟上的乙個新程式替換了當前程序的正文段、資料段、堆段、棧段。
7個不同的
exec
函式:
#include
int execl(const char *pathname, const char *arg0, ... /* (char *)0 */ );
int execv(const char *pathname, char *const argv);
int execle(const char *pathname, const char *arg0, ... /* (char *)0, char *const envp */ );
int execve(const char *pathname, char *const argv, char *const envp);
int execlp(const char *filename, const char *arg0, ... /* (char *)0 */ );
int execvp(const char *filename, char *const argv);
int fexecve(int fd, char *const argv, char *const envp);
返回值:成功不返回,出錯返回-1
七個exec
函式的區別:
(1).前四個取路徑名作為引數,後兩個取檔名作為引數,最後乙個以
fd作為引數
(2).參數列的傳遞不同(
l表示列表
list,v
表示向量
vector
)包含l
和包含v
(3).向新程式傳遞環境表不同。包含
e和不含e
七個exec
直接的關係如下圖,只有
execve
是核心的系統呼叫,另外
6個只是庫函式,它們最終都要呼叫該
execve
系統呼叫。
exec函式使用例程:
#include "apue.h"
#include char *env_init = ;
intmain(void)
else if (pid == 0)
if (waitpid(pid, null, 0) < 0)
err_sys("wait error");
if ((pid = fork()) < 0) else if (pid == 0)
exit(0);
}
echoall.c檔案**如下:
#include "apue.h"
intmain(int argc, char *argv)
這裡同樣是為了測試,我們sleep了100秒,模擬子程序的工作時間。
注意,需要預先把echoall.c
檔案程式設計,
gcc echoall.c -o echoall
,否則,當我們
exec
找到該檔案後無法執行。這樣,我們就完成了啟動子程序的一整個流程
unix環境高階程式設計 程序環境與程序控制
a 終止 i.程序終止 1.正常終止 return exit exit 系a exit與 exit 的區別 exit退出時按 atexit 註冊的相反順序呼叫註冊過的函式,對開啟的流呼叫 fclose 將緩衝區的資料寫到檔案上 重新整理緩衝區 exit 沒有 b exit與自然返回 return 的...
《unix高階環境程式設計》程序控制 程序ID
在unix系統中,每個程序都有乙個非負整型表示的唯一程序id。當乙個程序終止時,程序id可以重新被其他程序使用,為了防止誤判,unix系統實現延遲重用演算法,即新建的程序id不同於最近終止程序所使用的id。程序id為0的是排程程序,也稱為交換程序,是核心的一部分,不執行磁碟上的程式,因此也稱為系統程...
《unix高階環境程式設計》程序控制 程序時間
程序時間有牆上時鐘時間 使用者cpu時間和系統cpu時間。任一程序都可以呼叫 times 函式以獲得它自己以及終止子程序的上述值。cpp view plain copy 程序時間 返回值 若成功則返回流逝的牆上時鐘時間 單位 時鐘滴答數 若出錯則返回 1 函式原型 include clock t t...