首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

Linux 孤兒進程與殭屍進程深度解析(二):殭屍進程實戰演示

     編輯:關於C

承接上篇孤兒進程概念,本文聚焦殭屍進程:子進程結束而父進程未 wait/waitpid 回收,導致進程描述符滯留於系統進程表中,狀態顯示為 <defunct>。

殭屍進程形成條件

  • 子進程呼叫 exit() 終止。
  • 父進程未調用 wait() 或 waitpid() 讀取退出狀態。
  • 父進程仍在運行(若父進程先死,子進程被 init 收養,變為孤兒,由 init 回收,不會成殭屍)。

示範程式

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

int main() {
    pid_t pid = fork();
    if (pid == -1) {
        perror("fork");
        exit(1);
    } else if (pid == 0) {          // 子進程
        printf("child_pid pid=%d, ppid=%d\n", getpid(), getppid());
        exit(0);                    // 立即結束
    }
    // 父進程:不呼叫 wait,直接睡眠並查看進程狀態
    sleep(3);
    system("ps");                   // 列出當前進程
    exit(0);
}

編譯執行結果

$ ./a.out
child_pid pid=1108, ppid=1107
  PID TTY          TIME CMD
  847 pts/1    00:00:00 bash
 1107 pts/1    00:00:00 a.out
 1108 pts/1    00:00:00 a.out <defunct>   <-- 殭屍進程
 1109 pts/1    00:00:00 ps

危害與預防

  • 危害:殭屍進程佔用 PID(有限資源),大量積壓會導致無法建立新進程。
  • 預防:
    1. 父進程及時調用 wait()/waitpid() 回收。
    2. 設置 SIGCHLD 信號處理函數,在 handler 中 waitpid(-1, NULL, WNOHANG) 非阻塞回收。
    3. 雙重 fork 技巧:父進程 fork 子進程,子進程再 fork 孫進程並立即退出,孫進程由 init 收養,父進程只需等待子進程。

對比總結

特性孤兒進程殭屍進程
父進程狀態已終止仍在運行
收養者init (PID 1)無(等待父進程回收)
資源洩漏無(init 會回收)是(佔用 PID、進程表項)
ps 狀態正常<defunct>

理解兩者區別,是編寫健壯多進程 Linux 程式的基礎功課。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved