博客專欄

EEPW首頁 > 博客 > Linux孤兒進程和僵尸進程

Linux孤兒進程和僵尸進程

發(fā)布人:美男子玩編程 時間:2024-10-17 來源:工程師 發(fā)布文章

在 Linux 系統(tǒng)中,父子進程關(guān)系的生命周期不同,導(dǎo)致會產(chǎn)生兩類特殊進程:孤兒進程和僵尸進程。這兩類進程在系統(tǒng)資源管理中起著重要作用。


1


孤兒進程

孤兒進程指的是父進程先于子進程結(jié)束,導(dǎo)致子進程失去父進程。為了避免這些進程無人管理,Linux 系統(tǒng)自動將孤兒進程的父進程重定向為 init 進程(PID 1),這使得孤兒進程得以繼續(xù)運行,并由 init 進程負責(zé)在子進程結(jié)束時回收其資源。


當(dāng)父進程結(jié)束后,子進程可以通過 getppid() 系統(tǒng)調(diào)用獲取父進程的進程號。如果返回 1,則說明該子進程已經(jīng)成為孤兒進程,因為它的父進程變?yōu)榱?init。


孤兒進程的創(chuàng)建如下:


#include <stdio.h>#include <stdlib.h>#include <unistd.h> int main(void){    /* 創(chuàng)建子進程 */    switch (fork()) {        case -1:            perror("fork error");            exit(-1);        case 0: /* 子進程 */            printf("子進程<%d>被創(chuàng)建, 父進程<%d>n", getpid(), getppid());            sleep(3); //休眠 3 秒等待父進程結(jié)束            printf("父進程<%d>n", getppid()); // 父進程變?yōu)?nbsp;init,getppid() 返回 1            _exit(0);        default:            /* 父進程 */            break;    }    sleep(1); // 休眠 1 秒后父進程結(jié)束    printf("父進程結(jié)束!n");    exit(0);}


在這個代碼中,父進程在休眠 1 秒后結(jié)束,子進程在 3 秒后醒來并發(fā)現(xiàn)其父進程已經(jīng)變?yōu)?init 進程,通過 getppid() 驗證這一點。這種情況下,子進程變成了孤兒進程。


2


僵尸進程

僵尸進程是指子進程先于父進程結(jié)束,且父進程沒有及時回收子進程資源的情況。當(dāng)一個進程結(jié)束時,它的退出狀態(tài)仍然保留在系統(tǒng)進程表中,直到父進程調(diào)用 wait() 函數(shù)進行回收。如果父進程沒有調(diào)用 wait() 或其變體,子進程就會變成僵尸進程,占用系統(tǒng)資源。


如果系統(tǒng)中有大量僵尸進程,這些進程占用的資源將逐漸增加,最終可能耗盡進程表空間,導(dǎo)致無法創(chuàng)建新的進程。因此,及時調(diào)用 wait() 函數(shù)回收子進程非常重要。


僵尸進程的創(chuàng)建如下:


#include <stdio.h>#include <stdlib.h>#include <unistd.h> int main(void){    /* 創(chuàng)建子進程 */    switch (fork()) {        case -1:            perror("fork error");            exit(-1);        case 0:            /* 子進程 */            printf("子進程<%d>被創(chuàng)建n", getpid());            sleep(1);            printf("子進程結(jié)束n");            _exit(0); // 子進程結(jié)束        default:            /* 父進程 */            break;    }     for ( ; ; ) { // 父進程沒有調(diào)用 wait(),導(dǎo)致子進程變?yōu)榻┦M程        sleep(1);    }     exit(0);}


在這個代碼中,子進程在 1 秒后結(jié)束,而父進程沒有調(diào)用 wait() 函數(shù),這導(dǎo)致子進程進入僵尸狀態(tài)??梢酝ㄟ^ ps -aux 命令查看僵尸進程,其狀態(tài)標記為 Z (zombie)。


僵尸進程的清理方法:

  • 父進程調(diào)用 wait()當(dāng)父進程調(diào)用 wait() 函數(shù)后,僵尸進程將被內(nèi)核徹底移除。

  • 殺死父進程如果父進程沒有調(diào)用 wait(),我們可以通過殺死父進程,令 init 進程接管僵尸進程,從而清理它。


通過合理的進程管理,例如及時調(diào)用 wait(),可以有效防止僵尸進程的累積并保持系統(tǒng)的正常運行。

*博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。



關(guān)鍵詞: Linux 孤兒進程 僵尸進程

相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉