日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux进程实践(4) --wait避免僵尸进程

發布時間:2025/3/20 linux 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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非零,返回一個信號代碼

//示例 void printStatus(int status) {if (WIFEXITED(status)){cout << "normal termination, exit status = " << WEXITSTATUS(status) << endl;}else if (WIFSIGNALED(status)){cout << "abnormal termination, signal number = " << WTERMSIG(status); #ifdef WCOREDUMPif (WCOREDUMP(status))cout << " (core file generated)" << endl; #elsecout << endl; #endif // WCOREDUMP}else if (WIFSTOPPED(status)){cout << "child stopped, status number = " << WSTOPSIG(status) << endl;}else{cout << "Unknow Stop!" << endl;} }//測試代碼 int main() {pid_t pid = fork();if (pid == -1)err_exit("fork");else if (pid == 0)exit(7);int status;if (wait(&status) == -1)err_exit("first wait error");printStatus(status);pid = fork();if (pid == -1)err_exit("fork");else if (pid == 0)abort();if (wait(&status) == -1)err_exit("first wait error");printStatus(status);pid = fork();if (pid == -1)err_exit("fork");else if (pid == 0)status /= 0;if (wait(&status) == -1)err_exit("first wait error");printStatus(status);return 0; }

查看信號值


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避免僵尸进程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。