Linux下回收子進程wait函數和waitpid函數的基本使用


1. 孤兒進程:父進程先於子進程結束,則子進程成為孤兒進程,子進程的父進程變為init進程 。

2. 僵屍進程:子進程終止了,父進程尚未回收子進程,子進程殘留資源(PCB)存放於內核中,子進程變成僵屍(Zombie)進程。 

問:那為什么子進程要把PCB殘留在內核里呢? 

答:因為子進程終止后,它會把終止信號等退出狀態(不管正常終止還是異常終止都對應一個信號)保存在內核的PCB里面,只有這個子進程的父親節調用wait或者waitpid獲取這些退出狀態,然后才會徹底清除掉這個子進程。如果父進程不調用wait或者waitpid,那么這個子進程就會成為僵屍進程。

問:什么方法可以清除掉一個僵屍進程。(附:kill命令清除不了僵屍進程的,因為kill命令只是用來終止進程的,而僵屍進程已經是終止的了) 

答:kill確實是直接清除不掉僵屍進程,但是我們可以kill掉僵屍進程的父進程,這樣僵屍進程的父進程就變為init進程,init進程自然會調用wait或者waitpid清除這個僵屍進程。 

 

3. wait函數

pid_t wait(int *status); //status傳出參數,存放子進程的退出狀態信息

附:父進程一旦調用該函數,就會阻塞等待,直到子進程退出

返回值:成功返回子進程id,失敗返回-1(無子進程) 。

status傳出參數保存着子進程的退出狀態,下面對其說明如下:

if (WIFEXITED(status)) { //IFEXITED非0,進程正常退出
                        printf("exited, status=%d\n", WEXITSTATUS(status));
                    } else if (WIFSIGNALED(status)) { //IFSIGNALED非0,進程被某個信號異常終止
                        printf("killed by signal %d\n", WTERMSIG(status));
                    } else if (WIFSTOPPED(status)) { //IFSTOPPED非0,進程收到某個信號而暫停
                      printf("stopped by signal %d\n", WSTOPSIG(status));
                    } else if (WIFCONTINUED(status)) { //IFCONTINUED非0,進程從暫停狀態變為繼續運行狀態
                        printf("continued\n");
                   

4. waitpid函數 

pid_t waitpid(pid_t pid, int *status, int options); 

功能:和wait一樣,但是這個函數清除指定的pid,可以不阻塞父進程

返回值:成功返回清除掉的進程pid,失敗返回-1 (無子進程) 。當options指定為WNOHANG時,返回0表示子進程正在運行。

下面對pid的不同取值情況的說明:

>0  表示回收指定ID的子進程

-1   表示回收任意子進程(相當於wait)

0    表示回收和當前調用waitpid一個組的所有子進程

<-1 表示回收指定進程組內的任意子進程,比如-6610表示回收進程組id為6610的任意子進程

附:一次wait或waitpid調用只能清理掉一個子進程,清理多個子進程應該使用循環調用多次 。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM