1、何謂僵尸進(jìn)程?
在linux系統(tǒng)中,一個(gè)已經(jīng)終止但父進(jìn)程尚未對(duì)其進(jìn)行善后處理(釋放子進(jìn)程相關(guān)信息占用的資源)的子進(jìn)程叫做僵尸進(jìn)程。子進(jìn)程結(jié)束時(shí),父進(jìn)程調(diào)用pid_t wait(int *statloc)或者pid_t waitpid(pid_t pid,int *statloc,int options)獲取內(nèi)核中為子進(jìn)程保存的信息(進(jìn)程id,終止?fàn)顟B(tài))。
2、僵尸進(jìn)程避免分析
創(chuàng)建進(jìn)程時(shí),子進(jìn)程的終止?fàn)顟B(tài)要返回給父進(jìn)程,但調(diào)用fork函數(shù)時(shí)候,若父進(jìn)程比子進(jìn)程提前結(jié)束,則由init進(jìn)程領(lǐng)養(yǎng):在一個(gè)進(jìn)程終止時(shí)候,內(nèi)核逐個(gè)檢查所有活動(dòng)進(jìn)程,判斷它是否是被終止進(jìn)程的子進(jìn)程,如果是,則將該進(jìn)程父進(jìn)程的ID更改為1,這樣,每個(gè)進(jìn)程都有父進(jìn)程,init 進(jìn)程只要檢測(cè)有子進(jìn)程終止就會(huì)調(diào)用wait或waitpid釋放資源,防止僵尸進(jìn)程。
3、解決辦法:調(diào)用兩次fork避免僵尸進(jìn)程
#include "apue.h"
#include <sys/wait.h>
int main(void)
{
pid_t pid;
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) { // 第一個(gè)子進(jìn)程
if ((pid = fork()) < 0)
err_sys("fork error");
else if (pid > 0)
exit(0); //第二個(gè)子進(jìn)程的父進(jìn)程終止(第一個(gè)子進(jìn)程)
/*
* 這里是第二個(gè)子進(jìn)程(孤兒進(jìn)程),其父進(jìn)程已經(jīng)變成了init進(jìn)程,當(dāng)親生父進(jìn)程在上面調(diào)用exit()終止后,在此處繼續(xù)執(zhí) *行,當(dāng)?shù)诙€(gè)子進(jìn)程終止的時(shí)候,父進(jìn)程init會(huì)獲取其狀態(tài),從而避免僵尸進(jìn)程嗯。
*/
sleep(2); //保證父進(jìn)程優(yōu)先運(yùn)行(第一個(gè)子進(jìn)程)
printf("second child, parent pid = %d\n", getppid()); //獲取父進(jìn)程ID(即init ID,為1)
exit(0); //第二個(gè)子進(jìn)程終止
}
if (waitpid(pid, NULL, 0) != pid) //等待第一個(gè)子進(jìn)程
err_sys("waitpid error");
printf("i am the parents of your parents\n");
/*
* 這里是繼續(xù)執(zhí)行原始父進(jìn)程(第一個(gè)父進(jìn)程),且知道不是第二個(gè)子進(jìn)程的父進(jìn)程
*/
exit(0); //第一個(gè)父進(jìn)程終止
}
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)
點(diǎn)擊舉報(bào)。