🎁個人主頁:工藤新一1
🔍系列專欄:C++面向對象(類和對象篇)
🌟心中的天空之城,終會照亮我前方的路
🎉歡迎大家點贊👍評論📝收藏?文章
文章目錄
- 進程狀態 — 僵尸進程
- 一、進程狀態 — Zombies
- 二、僵尸進程
- 2.1 什么是僵尸進程?
- 2.2 為什么會有僵尸進程?
- 2.3 僵尸進程的危害?
- 2.4 如何產生一個僵尸進程?
- 2.5 如何清除僵尸進程?
- 2.6 如何避免僵尸進程?
進程狀態 — 僵尸進程
一、進程狀態 — Zombies
- Z (Zombies):進程已經執行完畢并終止了,但其父進程還沒有調用
wait()
或waitpid()
系統調用來回收它子進程退出狀態信息。此時,這個已經死亡的進程就成為了 “僵尸進程”。 - 重要:僵尸進程已經不占用任何內存或CPU資源,它僅僅在進程表中保留一個入口,記錄其退出狀態,供父進程查詢。如果父進程一直不回收,它就會一直存在 -(僵死進程會以終?狀態保持在進程表中,并且會?直在等待父進程讀取退出狀態代碼)
- 所以,只要子進程退出,父進程還在運行,但父進程沒有讀取子進程狀態,子進程進入 Z(Zombies) 狀態
二、僵尸進程
2.1 什么是僵尸進程?
故事插入:
如上所述,僵尸進程是一個已經終止但尚未被其父進程回收的進程。
2.2 為什么會有僵尸進程?
這是Unix系統進程狀態設計的一部分。設置僵尸狀態是為了維護進程的退出信息,以便父進程能夠查詢子進程是如何死掉的(是正常退出還是被信號殺死?退出碼是多少?)。
只有當父進程讀取了這些信息后,內核才會徹底清除這個僵尸進程。
1.那些信息:進程退出時,必須要維持進程的基本相關信息(哪些基本信息?),讓父進程得知其退出情況
2.信息存在哪里?當進程退出時,其退出信息是要保存在 task_struct
中(因為代碼、數據已經被釋放了,就只剩下 PCB
了),必須維持PCB(操作系統中的數據結構)。我們可以通過父進程的系統調用獲取到子進程的特殊信息,我們就知道這個進程是因為什么原因而退出的。所以在子進程已經退出之后,父進程沒有獲取子進程的信息之前,這個子進程就是僵尸進程
2.3 僵尸進程的危害?
- 資源占用:僵尸進程本身不消耗內存和CPU。
- 主要危害:每個僵尸進程都會在系統的進程表中占用一個槽位(即一個進程ID,PID)。如果系統中存在大量僵尸進程,進程表會被填滿,導致系統無法創建新的進程,從而引發嚴重問題。
- 內存泄漏問題
2.4 如何產生一個僵尸進程?
一個典型的例子:父進程創建了子進程,但父進程忙于自己的工作,沒有調用 wait()
來等待子進程結束。子進程先于父進程結束,就會變成僵尸。
簡單C代碼示例:
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>int main () {pid_t child_pid = fork(); // 創建子進程if (child_pid > 0) {// 父進程sleep(60); // 父進程睡眠60秒,而不調用 wait()// 在這60秒內,子進程已經結束,會成為僵尸} else {// 子進程exit(0); // 子進程立即退出}return 0;
}
編譯運行上述程序,在父進程睡眠的60秒內,用 ps aux | grep Z
命令就可以看到狀態為 Z+
的子進程。
驗證 “Z” 狀態
處于僵尸狀態的進程的PCB需一直維護,而PCB
本就是一個進程的 task_struct
的對象,這會一直占用內存空間 —— 引發內存泄漏問題!
所以,不是只有 new/malloc
會引起內存泄漏
,僵尸進程也會引起內存泄漏
—— 解決方法:通過 wait()_pid
的方式等待子進程并獲取子進程退出結果
因此,父進程在未來除了獲取子進程退出信息,還會進入等待模式將子進程的PCB釋放掉 —— 解決內存泄漏問題
2.5 如何清除僵尸進程?
- 正確方法:讓父進程調用
wait()
或waitpid()
來回收子進程。 - 常用方法:如果父進程不回收,最直接的方法就是殺死父進程。父進程被殺后,其所有子進程(包括僵尸進程)會變成“孤兒進程”,被 init 進程(PID=1)收養。init 進程會定期調用
wait()
,從而清理這些僵尸進程。- 命令:
kill <父進程的PID>
- 命令:
- 警告:不要試圖用
kill -9
殺死僵尸進程本身,因為它已經是死掉的進程,信號無法作用在它身上。
2.6 如何避免僵尸進程?
- 在編寫程序時,父進程應該使用
wait()
或waitpid()
系統調用來等待子進程結束。 - 或者,父進程可以捕獲
SIGCHLD
信號(當子進程狀態改變時,內核會向父進程發送此信號),并在信號處理函數中調用wait()
。
🌟 各位看官好,我是工藤新一1呀~
🌈 愿各位心中所想,終有所致!