久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > 孤兒(er)進程(cheng)和僵尸(shi)進程(cheng)

孤兒進程和僵尸進程 時間(jian):2018-08-15      來源(yuan):未(wei)知(zhi)

前段時間,由于(yu)研(yan)究經典面試題,把孤兒(er)進程和僵尸進程也總結了一下。

我們(men)有這樣一個問(wen)題:孤兒進程和(he)僵(jiang)尸進程,怎么產(chan)生的?有什么危害?怎么去預防(fang)?

下面是針對此問題(ti)的總結(jie)與概括。

一.產(chan)生(sheng)的原因

1) 一般進(jin)程(cheng)

正常情況下:子(zi)(zi)進(jin)程(cheng)(cheng)(cheng)由父進(jin)程(cheng)(cheng)(cheng)創建(jian),子(zi)(zi)進(jin)程(cheng)(cheng)(cheng)再創建(jian)新的(de)進(jin)程(cheng)(cheng)(cheng)。父子(zi)(zi)進(jin)程(cheng)(cheng)(cheng)是一個(ge)異步過(guo)程(cheng)(cheng)(cheng),父進(jin)程(cheng)(cheng)(cheng)永(yong)遠(yuan)無法預測子(zi)(zi)進(jin)程(cheng)(cheng)(cheng)的(de)結(jie)束,所(suo)以(yi),當子(zi)(zi)進(jin)程(cheng)(cheng)(cheng)結(jie)束后(hou),它的(de)父進(jin)程(cheng)(cheng)(cheng)會調(diao)用wait()或waitpid()取得子(zi)(zi)進(jin)程(cheng)(cheng)(cheng)的(de)終止狀態,回收掉(diao)子(zi)(zi)進(jin)程(cheng)(cheng)(cheng)的(de)資源(yuan)。

2)孤兒進程

孤兒進(jin)程(cheng):父進(jin)程(cheng)結束了(le),而它的(de)一個(ge)或(huo)多(duo)個(ge)子進(jin)程(cheng)還在(zai)運行,那么(me)這(zhe)些子進(jin)程(cheng)就成為孤兒進(jin)程(cheng)(father died)。子進(jin)程(cheng)的(de)資源由init進(jin)程(cheng)(進(jin)程(cheng)號PID = 1)回(hui)收。

3)僵尸進程

僵尸(shi)進(jin)(jin)(jin)(jin)程(cheng):子(zi)(zi)進(jin)(jin)(jin)(jin)程(cheng)退出了,但是父(fu)進(jin)(jin)(jin)(jin)程(cheng)沒有用(yong)wait或waitpid去獲取子(zi)(zi)進(jin)(jin)(jin)(jin)程(cheng)的狀態信息,那么子(zi)(zi)進(jin)(jin)(jin)(jin)程(cheng)的進(jin)(jin)(jin)(jin)程(cheng)描述(shu)符仍然保存(cun)在系統中,這種進(jin)(jin)(jin)(jin)程(cheng)稱為僵死(si)進(jin)(jin)(jin)(jin)程(cheng)。

二.問題危害

 注意:unix提供了一(yi)種機制保(bao)證父進程知道(dao)子(zi)進程結束時的狀態(tai)信(xin)息。

這種機(ji)制是:在每個進程退出的時(shi)候,內(nei)核會釋放(fang)所(suo)有的資源,包(bao)括(kuo)打開的文件,占用(yong)的內(nei)存(cun)等。但是仍(reng)保留一部(bu)分信息(進程號(hao)PID,退出狀態,運行時(shi)間等)。直到父進程通過wait或(huo)waitpid來取時(shi)才釋放(fang)。

但是(shi)這(zhe)樣就會產(chan)生問題:如(ru)果(guo)(guo)父(fu)進(jin)(jin)程(cheng)(cheng)不調用(yong)(yong)wait或waitpid的(de)(de)話,那(nei)么保留(liu)的(de)(de)信息就不會被釋放,其(qi)進(jin)(jin)程(cheng)(cheng)號(hao)(hao)就會被一直占用(yong)(yong),但是(shi)系統所能(neng)使用(yong)(yong)的(de)(de)進(jin)(jin)程(cheng)(cheng)號(hao)(hao)是(shi)有(you)限的(de)(de),如(ru)果(guo)(guo)大量產(chan)生僵死進(jin)(jin)程(cheng)(cheng),將因(yin)沒有(you)可用(yong)(yong)的(de)(de)進(jin)(jin)程(cheng)(cheng)號(hao)(hao)而導致系統無法產(chan)生新的(de)(de)進(jin)(jin)程(cheng)(cheng),這(zhe)就是(shi)僵尸進(jin)(jin)程(cheng)(cheng)的(de)(de)危害

孤兒(er)進(jin)程(cheng)是沒(mei)(mei)有(you)父進(jin)程(cheng)的進(jin)程(cheng),它由(you)init進(jin)程(cheng)循環的wait()回(hui)收資源,init進(jin)程(cheng)充當父進(jin)程(cheng)。因此孤兒(er)進(jin)程(cheng)并沒(mei)(mei)有(you)什(shen)么危害。

補充:任(ren)何一(yi)個子進(jin)(jin)程(cheng)(cheng)(init除外)在(zai)exit()之(zhi)后,并非馬上就消(xiao)失掉,而是(shi)(shi)留下一(yi)個稱為僵尸進(jin)(jin)程(cheng)(cheng)的數據結構,等待(dai)父(fu)進(jin)(jin)程(cheng)(cheng)去處理。如(ru)果父(fu)進(jin)(jin)程(cheng)(cheng)在(zai)子進(jin)(jin)程(cheng)(cheng)exit()之(zhi)后,沒(mei)有(you)及時(shi)處理,出現僵尸進(jin)(jin)程(cheng)(cheng),并可以用ps命令去查看,它的狀態是(shi)(shi)“Z”。

三(san).解決方案

1)kill殺死元(yuan)兇父進程(cheng)(一般不(bu)用)

嚴格的說,僵(jiang)(jiang)尸(shi)進(jin)(jin)程(cheng)(cheng)(cheng)并不是問(wen)題的根(gen)源(yuan),罪魁禍(huo)首是產生(sheng)大量僵(jiang)(jiang)死進(jin)(jin)程(cheng)(cheng)(cheng)的父(fu)進(jin)(jin)程(cheng)(cheng)(cheng)。因此,我(wo)們可以直接除掉元(yuan)兇,通(tong)過kill發送SIGTERM或者SIGKILL信號。元(yuan)兇死后,僵(jiang)(jiang)尸(shi)進(jin)(jin)程(cheng)(cheng)(cheng)進(jin)(jin)程(cheng)(cheng)(cheng)變成(cheng)孤兒進(jin)(jin)程(cheng)(cheng)(cheng),由init充當父(fu)進(jin)(jin)程(cheng)(cheng)(cheng),并回收資源(yuan)。

或者運行:kill -9 父進程的(de)pid值、

2)父進程(cheng)用wait或(huo)waitpid去回收(shou)資源(方案不好)

父進(jin)(jin)程(cheng)(cheng)(cheng)通過wait或waitpid等(deng)函數去(qu)等(deng)待子進(jin)(jin)程(cheng)(cheng)(cheng)結束,但是不好,會導(dao)致父進(jin)(jin)程(cheng)(cheng)(cheng)一(yi)直等(deng)待被(bei)掛起,相當(dang)于一(yi)個進(jin)(jin)程(cheng)(cheng)(cheng)在干活,沒(mei)有(you)起到(dao)多進(jin)(jin)程(cheng)(cheng)(cheng)的作用。

3)通過信(xin)號機(ji)制(zhi),在(zai)處理函(han)數中調(diao)用wait,回收資(zi)源

通過信(xin)號(hao)機制(zhi),子(zi)進(jin)程(cheng)退出(chu)時向(xiang)父進(jin)程(cheng)發送SIGCHLD信(xin)號(hao),父進(jin)程(cheng)調用(yong)signal(SIGCHLD,sig_child)去(qu)處理SIGCHLD信(xin)號(hao),在信(xin)號(hao)處理函數sig_child()中調用(yong)wait進(jin)行處理僵尸進(jin)程(cheng)。什(shen)么時候(hou)得到子(zi)進(jin)程(cheng)信(xin)號(hao),什(shen)么時候(hou)進(jin)行信(xin)號(hao)處理,父進(jin)程(cheng)可以(yi)繼續(xu)干其他活(huo),不用(yong)去(qu)阻塞(sai)等待(dai)。

例子1:

#include

#include

#include

#include

#include

static void sig_child(int signo);

int main()

{

pid_t pid;

//創(chuang)建捕捉子進程退出信(xin)號

signal(SIGCHLD,sig_child);

pid = fork();

if (pid < 0)

{

perror("fork error:");

exit(1);

}

else if (pid == 0)

{

printf("I am child process,pid id %d.I am exiting.\n",getpid());

exit(0);

}

printf("I am father process.I will sleep two seconds\n");

//等待(dai)子進程先(xian)退(tui)出(chu)

sleep(2);

//輸(shu)出進(jin)程(cheng)信息

system("ps -o pid,ppid,state,tty,command");

printf("father process is exiting.\n");

return 0;

}

static void sig_child(int signo)

{

pid_t pid;

int stat;

//處理僵尸進程

while ((pid = waitpid(-1, &stat, WNOHANG)) >0)

printf("child %d terminated.\n", pid);

}

4)fork兩(liang)次(ci)

fork兩次,父(fu)進程(cheng)(cheng)(cheng)fork一個子(zi)進程(cheng)(cheng)(cheng),子(zi)進程(cheng)(cheng)(cheng)在fork出一個孫子(zi)進程(cheng)(cheng)(cheng),然后子(zi)進程(cheng)(cheng)(cheng)立馬退出,并(bing)由父(fu)進程(cheng)(cheng)(cheng)去wait回(hui)(hui)收,這(zhe)個過程(cheng)(cheng)(cheng)不需要等(deng)待,然后父(fu)進程(cheng)(cheng)(cheng)可以去干(gan)其他的活。孫子(zi)進程(cheng)(cheng)(cheng)因為(wei)子(zi)進程(cheng)(cheng)(cheng)退出會成(cheng)為(wei)孤兒進程(cheng)(cheng)(cheng),那它可以由init充當父(fu)進程(cheng)(cheng)(cheng),并(bing)回(hui)(hui)收。這(zhe)樣父(fu)進程(cheng)(cheng)(cheng)和孫子(zi)進程(cheng)(cheng)(cheng)就(jiu)可以同時(shi)干(gan)活,互不影(ying)響,就(jiu)實(shi)現了(le)多(duo)進程(cheng)(cheng)(cheng)。

例子2:

#include

#include

#include

#include

int main()

{

pid_t pid;

//創建第一個(ge)子進程

pid = fork();

if (pid < 0)

{

perror("fork error:");

exit(1);

}

//第一個子進程

else if (pid == 0)

{

//子(zi)(zi)進程再(zai)創(chuang)建(jian)子(zi)(zi)進程

printf("I am the first child process.pid:%d\tppid:%d\n",getpid(),getppid());

pid = fork();

if (pid < 0)

{

perror("fork error:");

exit(1);

}

//第一(yi)個子進程退(tui)出

else if (pid >0)

{

printf("first procee is exited.\n");

exit(0);

}

//第二個子進程

//睡眠3s保證第一(yi)個子(zi)(zi)進(jin)(jin)程退出,這樣第二個子(zi)(zi)進(jin)(jin)程的父親(qin)就是init進(jin)(jin)程里

sleep(3);

printf("I am the second child process.pid: %d\tppid:%d\n",getpid(),getppid());

exit(0);

}

//父進(jin)(jin)程處理(li)第一個子進(jin)(jin)程退出

if (waitpid(pid, NULL, 0) != pid)

{

perror("waitepid error:");

exit(1);

}

exit(0);

return 0;

}

四.補充測試(shi)程(cheng)序

1)孤兒進程(cheng)測試程(cheng)序

#include

#include

#include

#include

int main()

{

pid_t pid;

//創建一個進程(cheng)

pid = fork();

//創建失敗

if (pid < 0)

{

perror("fork error:");

exit(1);

}

//子進程

if (pid == 0)

{

printf("I am the child process.\n");

//輸出進(jin)程(cheng)ID和父進(jin)程(cheng)ID

printf(&quot;pid: %d\tppid:%d\n",getpid(),getppid());

printf(&quot;I will sleep five seconds.\n");

//睡(shui)眠(mian)5s,保證父進程先退出

sleep(5);

printf("pid: %d\tppid:%d\n";,getpid(),getppid());

printf("child process is exited.\n");

}

//父進程

else

{

printf("I am father process.\n");

//父進程睡眠1s,保證子進程輸(shu)出進程id

sleep(1);

printf("father process is exited.\n");

}

return 0;

}

2)僵(jiang)尸(shi)進程測(ce)試程序1

int main()

{

pid_t pid;

pid = fork();

if (pid < 0)

{

perror("fork error:");

exit(1);

}

else if (pid == 0)

{

printf("I am child process.I am exiting.\n");

exit(0);

}

printf("I am father process.I will sleep two seconds\n");

//等待子進程先退(tui)出

sleep(2);

//輸出進程(cheng)信(xin)息

 system("ps -o pid,ppid,state,command");

printf("father process is exiting.\n");

return 0;

}

3)僵(jiang)尸進(jin)程測試程序2

#include

#include

#include

#include

int main()

{

pid_t pid;

//循環(huan)創建子進(jin)程

while(1)

{

pid = fork();

if (pid < 0)

{

perror("fork error:");

exit(1);

}

else if (pid == 0)

{

printf("I am a child process.\nI am exiting.\n");

//子進(jin)程退出,成為僵尸進(jin)程

exit(0);

}

else

{

//父進程休眠20s繼續創建子進程

sleep(20);

continue;

}

}

return 0;

}

4)僵(jiang)尸進程(cheng)測(ce)試程(cheng)序2--測(ce)試效果

運行(xing)可執行(xing)程序顯示(shi):

I am a child process.

I am exiting.

I am a child process.

I am exiting.

I am a child process.

I am exiting.

I am a child process.

I am exiting.

I am a child process.

I am exiting.

I am a child process.

I am exiting.

Killed

開另外一個終端:

運行:

ps -a -o pid,ppid,state,cmd

顯(xian)示:(狀(zhuang)態Z代表僵(jiang)尸進程(cheng))

S PID PPID CMD

S 3213 2529 ./pid1

Z 3214 3213 [pid1]

Z 3215 3213 [pid1]

Z 3219 3213 [pid1]

Z 3220 3213 [pid1]

Z 3221 3213 [pid1]

R 3223 3104 ps -a -o state,pid,ppid,cmd

用第一種(zhong)方法,解(jie)決(jue)僵尸進(jin)程,殺死其父(fu)進(jin)程

運行(xing):kill -9 3213

注意:僵尸進程(cheng)(cheng)無法用kill直接(jie)殺死(si),如kill -9 3214,再用上(shang)面命令去查(cha)看進程(cheng)(cheng)狀態,發現3214進程(cheng)(cheng)還(huan)在。

五. 參考文獻

//www.cnblogs.com/Anker/p/3271773.html

《unix環境高級編程(cheng)》第八章

上一篇:Linux C中對json格式數組數據的生成與解析

下一篇:傳感器尺寸

熱點文(wen)章推薦
華清學員就(jiu)業榜(bang)單(dan)
高薪學員經驗(yan)分享(xiang)
熱點新聞推薦
前臺專線:010-82525158 企業培訓(xun)洽(qia)談專線:010-82525379 院校合(he)作洽(qia)談(tan)專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,,京公海網安備11010802025203號

回到頂部