歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> 孤兒進程與僵屍進程

孤兒進程與僵屍進程

日期:2017/3/3 11:05:54   编辑:Linux技術

早就了解孤兒進程與僵屍進程,但僅僅是停留在一知半解的程度,總結一下。

概念

  首先我們知道在Linux中,進程都是由父進程創建的,一般情況下子進程退出後需要父進程來清理子進程退出後留下的“垃圾”,父進程是調用wait()或waitpid()系統調用獲得的子進程的終止狀態。 孤兒進程:父進程在它的子進程結束之前就退出了,那麼這些子進程就成為孤兒進程。孤兒進程會被init(pid=1)進程所收養,回收這些孤兒進程。

僵屍進程:父進程創建了子進程,若子進程退出,但是父進程並沒有調用wait()或者waitpid()獲取子進程的狀態,那麼子進程的進程描述符就仍然保存在系統中。這些進程稱為僵屍進程。

危害

若一個進程產生子進程後不調用wait()或waitpid()的話,那麼子進程退出後的進程描述符不會釋放,進程號也就一直被占用,但是系統使用的進程號是有限的,如果大量產生僵屍進程,就有可能導致系統沒有可用的進程號了而不能產生新進程,這就是僵屍進程的危害

孤兒進程沒有父進程來回收,重任就交給了init進程上,在孤兒進程結束後init會作為父進程進行回收,所以孤兒進程一般沒有什麼危害

僵屍進程的解決辦法

子進程在exit()退出之後,內核會釋放掉進程的相關資源,留下進程描述符等一些信息等待父進程回收,這個狀態稱為僵屍進程,這時用ps命令就能看到子進程的轉態是“Z”。退出的同時也會給父進程發送一個SIGCHILD信號

解決辦法一:

父進程主動接收並處理SIGCHILD信號,在信號處理函數中調用wait()函數進程處理。

[code]int main()
{
    ...
    Signal(SIGCHLD, sig_chld);
    ...
}
void sig_chld(int signo)
{
    pid_t        pid;
    int        stat;

    while ( (pid = waitpid(-1, &stat, WNOHANG)) >0)
        printf("child %d terminated/n", pid);
}
解決辦法二:

fork兩次,父進程(成為進程a)創建子進程(進程b),然後子進程再創建子進程(進程c),同時進程b退出且父進程回收,這時進程c變成孤兒進程,從而其父進程變成init進程,通過init進程就能處理僵屍進程。

Copyright © Linux教程網 All Rights Reserved