在進程運行時,由於某些原因會產生殭屍進程和孤兒進程,殭屍和孤兒兩個詞語形象的體現某進程的運行狀態
殭屍進程:當進程加載到內存中時,需要向操作系統申請資源,正常情況下,當一個進程正常退出時,這個進程的資源會被他的父進程或者操作系統回收,如果這些資源在進程退出時沒有被操作系統回收,就像一具已經僵硬的屍體,沒人處理,形象的稱這個進程爲殭屍進程,如果殭屍進程一直不被回收,就造成了內存泄漏,試想一下,如果系統中的殭屍進程越來越多,操作系統自己的資源就越來越少,直到系統崩潰,下面模擬一下這種情況:
#include<stdio.h>
#include<unistd.h>
int main() {
pid_t pid = fork();
if(pid < 0) {
perror("fork");
return 1;
}
else if(pid == 0) {
//子進程
printf("我是子進程~~\n");
sleep(3);
printf("子進程退出~~\n");
}
else {
//父進程
printf("我是父進程~~\n");
sleep(5);
printf("父進程異常退出~~\n");
exit(1);
}
return 0;
}
運行結果:
在另一個窗口寫一個監測a.out進程的shell腳本:while :;do ps aux | grep a.out | grep -v grep; sleep 1; echo "--------------------------------------------";done 在程序運行之後,監測到有這個進程如下圖
在三秒後,子進程退出,這時父進程正在做自己的事情,子進程處於殭屍狀態,正在等待父進程查看他的退出碼,但在五秒之後父進程異常退出,異常退出的父進程應該沒有能力去處理殭屍狀態的子進程,但是發現在父進程結束之後,子進程也隨即消失,爲什麼???,這個問題在孤兒進程之後回答
孤兒進程:假如一個父進程創建了一個子進程,父進程先退出,子進程就變成了孤兒進程,下面模擬一下孤兒進程:
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main() {
pid_t pid = fork();
if(pid < 0) {
perror("fork");
return 1;
}
else if(pid == 0) {
//子進程
printf("我是子進程~~\n");
pid_t ppid = getppid();
printf("c: my ppid :%d\n", ppid);
sleep(5);
ppid = getppid();
printf("c: my ppid :%d\n", ppid);
printf("子進程退出~~\n");
}
else {
//父進程
printf("我是父進程~~\n");
sleep(3);
printf("父進程退出~~\n");
}
return 0;
}
實驗結果:
就算子進程變成了孤兒進程,但是當他退出時,資源依然需要被父進程回收,不然就變成了殭屍進程,其實情況也沒有那麼悲觀,當一個子進程的父進程退出後,該子進程就會被操作系統的1號進程領養,當這個子進程退出時,他的資源就由操作系統回收
那麼殭屍進程的資源如何回收?
1.子進程結束後,操作系統會發送SIGCHLD信號給父進程,父進程收到這個信號以後,執行waitpid()函數來回收子進程的資源
2.如果父進程異常退出,殭屍進程成爲"孤兒進程",過繼給1號進程init,1號進程就會回收這個子進程的資源