Linux进程实践(4) --wait避免僵尸进程
Wait的背景
? ?當子進程退出的時候,內核會向父進程發送SIGCHLD信號,子進程的退出是個異步事件(子進程可以在父進程運行的任何時刻終止)
? ?子進程退出時,內核將子進程置為僵尸狀態,這個進程稱為僵尸進程,它只保留最小的一些內核數據結構,以便父進程查詢子進程的退出狀態。
? ?父進程查詢子進程的退出狀態可以用wait/waitpid函數
#include <sys/types.h> #include <sys/wait.h> pid_t wait(int *status); pid_t waitpid(pid_t pid, int *status, int options);Wait
pid_t wait(int *status);? 當我們用fork啟動一個進程時,子進程就有了自己的生命,并將獨立地運行。有時,我們需要知道某個子進程是否已經結束了,這樣我們可以通過wait安排父進程在子進程結束之后。
? status:該參數可以獲得你等待子進程的信息
返回值:
? on?success,?returns?the?process?ID?of?the?terminated?child;??on??error,??-1??is?returned.
特征:
? 1.wait系統調用會使父進程暫停執行,直到它的任意一個(并不是所有的)子進程結束為止。
? 2.返回的是子進程的PID,它通常是已經結束了的子進程;
? 3.狀態信息允許父進程判定子進程的退出狀態,即從子進程的main函數返回的值或子進程中exit/_exit語句的退出碼。
? 4.如果status不是一個空指針,狀態信息將被寫入它指向的位置
//示例 int main() {pid_t pid = fork();if (pid == -1)err_exit("fork");else if (pid == 0){cout << "In Child, pid = " << getpid() << endl;sleep(5);exit(10);}int status;int returnPid = wait(&status);//兩個pid的值相同,但是status的值根本不是10cout << "In Parent, returnPid = " << returnPid<< ", status = " << status << endl; }Wait獲取status
宏定義 | 描述 |
WIFEXITED(status) ?????WEXITSTATUS(status) | 如果子進程正常結束,返回一個非零值 ????如果WIFEXITED非零,返回子進程退出碼 |
WIFSIGNALED(status) ?????WTERMSIG(status) | 子進程因為捕獲信號而終止,返回非零值 ????如果WIFSIGNALED非零,返回信號代碼 |
WIFSTOPPED(status) ?????WSTOPSIG(status) | 如果子進程被暫停,返回一個非零值 ????如果WIFSTOPPED非零,返回一個信號代碼 |
查看信號值
Waitpid
pid_t waitpid(pid_t pid, int *status,int options)等待某個特定進程的結束
參數:
Pid:The?value?of?pid?can?be:
? <-1??? meaning?wait?for?any?child?process?whose?process?group?ID?is?equal?to?the?absolute?value?of?pid.
??-1????? meaning?wait?for?any?child?process(任一子進程).
???0?????? meaning?wait?for?any?child?process?whose?process?group?ID?is?equal?to?that?of??the?calling?process(與調用者進程同在一個組的進程).
??>0???? meaning?wait?for?the?child?whose?process?ID?is?equal?to?the?value?of?pid.
status:如果不是空,會把狀態信息寫到它指向的位置(同wait)
options:允許改變waitpid的行為,最有用的一個選項是WNOHANG,它的作用是防止waitpid把調用者的執行掛起
返回值:
??如果成功返回等待子進程的ID,失敗返回-1
?
wait與waitpid的區別:
??1.在一個子進程終止前,?wait?使其調用者阻塞,而waitpid?有一選擇項,可使調用者不阻塞。
??2.waitpid并不等待第一個終止的子進程:它有若干個選擇項,可以控制它所等待的特定進程。
??3.wait函數相當于是waitpid函數的一個特例。
waitpid(-1,?&status,?0);
?
僵尸進程(如果不等待...)
??當一個子進程結束運行時,它與其父進程之間的關聯還會保持到父進程也正常地結束運行或者父進程調用了wait才告終止。
??進程表中代表子進程的數據項是不會立刻釋放的,雖然不再活躍了,可子進程還停留在系統里,因為它的退出碼還需要保存起來以備父進程中后續的wait調用使用。它將稱為一個“僵尸進程”
?
如何避免僵尸進程
??方法1:調用wait或者waitpid函數查詢子進程退出狀態。
??方法2:如果不想讓父進程掛起,可以在父進程中加入一條語句:signal(SIGCHLD,SIG_IGN);表示父進程忽略SIGCHLD信號,該信號是子進程退出的時候向父進程發送的(表明父進程忽略SIGCHLD信號,一切讓Linux內核管理)。
附-利用man手冊,減少開發難度,提高開發技能
如:Man?7?signal?查找有什么信號可以使應用程序暫停
轉載于:https://www.cnblogs.com/itrena/p/5926973.html
總結
以上是生活随笔為你收集整理的Linux进程实践(4) --wait避免僵尸进程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HTML5开发手机应用--viewpor
- 下一篇: 【BZOJ】【2154】Crash的数字