Linux---模擬實現殭屍進程和孤兒進程

我們先了解一下進程都有哪幾種狀態。
kernel源代碼裏定義了進程的如下狀態:
· R 運行狀態(running):表明進程要麼是在運行中要麼是在運行隊列裏。
· S 睡眠狀態(sleeping):意味着進程在等待事件完成,有時叫做可中斷睡眠。
· D磁盤休眠狀態(Disk sleep):不可中斷睡眠狀態,在這個狀態進程通常會等待I/O的結束。
· T 停止狀態(stopped):可以通過發送SIGSTOP信號給進程來停止進程。這個暫停的進程可以通過發送SIGCONT信號讓進程繼續運行。
· X 死亡狀態(dead):只是一個返回狀態,不會在任務列表裏看到。
· Z 殭屍狀態(zombie):當進程退出並且父進程沒有讀取到子進程退出的返回代碼時就會產生殭屍狀態。殭屍進城會以終止狀態保持在進程表中,會一直等待父進程讀取退出狀態信息。

我們知道,在unix/linux中,正常情況下,子進程由父進程創建,子進程可以再創建新進程。子進程的退出和父進程的運行是一個異步的過程,即父進程永遠無法預測子進程到底什麼時候結束。當一個進程完成它的工作終止之後,它的父進程需要調用wait()或者waitpid()系統調用取得子進程的終止狀態。
1.殭屍進程
父進程通過fork()創建子進程,子進程退出後,父進程並沒有調用wait或waitpid獲取子進程的狀態信息,這時子進程就成爲殭屍進程。
測試代碼:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main()
{
    pid_t pid = fork();//創建子進程
    if(pid < 0)
    {
        perror("fork error");
        exit(1);
    }
    else if(pid == 0)//子進程
    {
        printf("child process [%d] is running!\n",getpid());
        sleep(5);
        exit(EXIT_SUCCESS);//5秒後子進程退出
    }
    else//父進程
    {
        printf("I am father!\n");
        sleep(20);
        printf("father process [%d] is running!\n",getpid());

    }
    return 0;
}

測試結果:
這裏寫圖片描述
殭屍進程的危害:
我們知道,在創建進程的時候會給他分配相應的系統資源,如果子進程退出後,父進程不進行回收,那麼它所佔用的那塊資源也就不會釋放,就會造成內存泄露。

2.孤兒進程
一個父進程退出,而它的一個或多個子進程還在運行,那麼那些子進程將成爲孤兒進程。孤兒進程將被init進程(進程號爲1)所收養,並由init進程對它們完成狀態收集工作。
測試代碼:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main()
{
    pid_t pid = fork();//創建子進程
    if(pid < 0)
    {
        perror("fork error");
    }
    else if(pid == 0)//子進程
    {
        printf("I am child [%d] ,I am running.[%d] is my father!\n",getpid(),getppid());
        sleep(20);
    }
    else//父進程
    {
        printf("I am father [%d],I will die soon!\n",getpid());
        sleep(10);
        exit(EXIT_SUCCESS);//10秒後父進程退出
    }
    return 0;
}

測試結果:
這裏寫圖片描述
10秒後,父進程退出,子進程被1號進程收養。
這裏寫圖片描述

發佈了56 篇原創文章 · 獲贊 13 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章