久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Linux中的僵尸進(jìn)程

 幸福的樂(lè)土 2012-02-16

解釋一:[1,2]

Unix編程中所謂"僵尸進(jìn)程"指什么,,什么情況下會(huì)產(chǎn)生僵尸進(jìn)程,,如何殺掉僵尸進(jìn)程:

fork()/execve()過(guò)程中,,假設(shè)子進(jìn)程結(jié)束時(shí)父進(jìn)程仍存在,,而父進(jìn)程fork()之前既沒(méi)安裝SIGCHLD信號(hào)處理函數(shù)調(diào)用waitwaitpid()等待子進(jìn)程結(jié)束,又沒(méi)有顯式忽略該信號(hào),,則子進(jìn)程成為僵尸進(jìn)程,,無(wú)法正常結(jié)束,此時(shí)即使是root身份kill -9也不能殺死僵尸進(jìn)程(僵死進(jìn)程實(shí)際上是已死的進(jìn)程,,你當(dāng)然不能殺死一個(gè)死人)

●在一個(gè)進(jìn)程調(diào)用了exit之后,,該進(jìn)程并非馬上就消失掉,,而是留下一個(gè)稱為僵尸進(jìn)程(Zombie)的數(shù)據(jù)結(jié)構(gòu)。在Linux進(jìn)程的5種狀態(tài)中,,僵尸進(jìn)程是非常特殊的一種,,它已經(jīng)放棄了幾乎所有內(nèi)存空間,沒(méi)有任何可執(zhí)行代碼,,也不能被調(diào)度,,僅僅在進(jìn)程列表中保留一個(gè)位置,記載該進(jìn)程的退出狀態(tài)等信息供其他進(jìn)程收集(如供父進(jìn)程),,除此之外,,僵尸進(jìn)程不再占有任何內(nèi)存空間。從這點(diǎn)來(lái)看,,僵尸進(jìn)程雖然有一個(gè)很酷的名字,,但它的影響力遠(yuǎn)遠(yuǎn)抵不上那些真正的僵尸兄弟,真正的僵尸總能令人感到恐怖,,而僵尸進(jìn)程卻除了留下一些供人憑吊的信息,,對(duì)系統(tǒng)毫無(wú)作用。

●系統(tǒng)調(diào)用exit,,它的作用是使進(jìn)程退出,,但也僅僅限于將一個(gè)正常的進(jìn)程變成一個(gè)僵尸進(jìn)程,并不能將其完全銷毀,。僵尸進(jìn)程雖然對(duì)其他進(jìn)程幾乎沒(méi)有什么影響,,不占用CPU時(shí)間,消耗的內(nèi)存也幾乎可以忽略不計(jì),,但有它在那里呆著,,還是讓人覺(jué)得心里很不舒服。而且Linux系統(tǒng)中進(jìn)程數(shù)目是有限制的,,在一些特殊的情況下,,如果存在太多的僵尸進(jìn)程,也會(huì)影響到新進(jìn)程的產(chǎn)生,。

●如何清理僵尸進(jìn)程:用wait()waitpid()系統(tǒng)調(diào)用可以清理僵尸進(jìn)程,或者殺死僵尸進(jìn)程的父進(jìn)程(僵尸進(jìn)程的父進(jìn)程必然存在),,僵尸進(jìn)程成為"孤兒進(jìn)程",過(guò)繼給1號(hào)進(jìn)程init,,init始終會(huì)負(fù)責(zé)清理僵尸進(jìn)程,。

下面這段比喻形容了進(jìn)程的一生,也更容易看出僵尸進(jìn)程所處的階段:

隨著一句fork,一個(gè)新進(jìn)程呱呱落地,,但它這時(shí)只是老進(jìn)程的一個(gè)克隆,。

然后隨著exec,新進(jìn)程脫胎換骨,離家獨(dú)立,,開(kāi)始了為人民服務(wù)的職業(yè)生涯,。

人有生老病死,進(jìn)程也一樣,,它可以是自然死亡,,即運(yùn)行到main函數(shù)的最后一個(gè)"}",從容地離我們而去,;也可以是自殺,,自殺有2種方式,一種是調(diào)用exit函數(shù),,一種是在main函數(shù)內(nèi)使用return,,無(wú)論哪一種方式,它都可以留下遺書,,放在返回值里保留下,;它還甚至能可被謀殺,被其它進(jìn)程通過(guò)另外一些方式結(jié)束他的生命,。

進(jìn)程死掉以后,,會(huì)留下一具僵尸,waitwaitpid充當(dāng)了殮尸工,,把僵尸推去火化,,使其最終歸于無(wú)形。

這就是進(jìn)程完整的一生,。[1,2]

處理:

*顯式忽略SIGCHLD信號(hào)是指類似這樣的代碼:

signal( SIGCHLD, SIG_IGN );

*安裝SIGCHLD信號(hào)句柄是指類似這樣的代碼:

View Code
static void on_sigchld ( int signo ) 
...{
pid_t pid;
int status;
while ( ( pid = waitpid( -1, &status, WNOHANG ) ) > 0 )
...{
/*
演示用,,不推薦在信號(hào)句柄中使用fprintf()
*/
fprintf( stderr,
"child <%u> terminated", ( unsigned int )pid );
}
return;
}
/**//* end of on_sigchld */
... ...
signal( SIGCHLD, on_sigchld );

當(dāng)然,不建議使用signal(),,應(yīng)該使用sigaction(),。[1]

解釋二:[3]

僵尸進(jìn)程中保存著很多對(duì)程序員和系統(tǒng)管理員非常重要的信息,首先,,這個(gè)進(jìn)程是怎么死亡的,?是正常退出呢,還是出現(xiàn)了錯(cuò)誤,,還是被其它進(jìn)程強(qiáng)迫退出的,?其次,這個(gè)進(jìn)程占用的總系統(tǒng)CPU時(shí)間和總用戶 CPU時(shí)間分別是多少,?發(fā)生頁(yè)錯(cuò)誤的數(shù)目和收到信號(hào)的數(shù)目,。這些信息都被存儲(chǔ)在僵尸進(jìn)程中,試想如果沒(méi)有僵尸進(jìn)程,,進(jìn)程一退出,,所有與之相關(guān)的信息都立刻歸于無(wú)形,而此時(shí)程序員或系統(tǒng)管理員需要用到,,就只好干瞪眼了,。

那么,我們?nèi)绾问占@些信息,,并終結(jié)這些僵尸進(jìn)程呢,?就要靠waitpid調(diào)用和wait調(diào)用。這兩者的作用都是收集僵尸進(jìn)程留下的信息,,同時(shí)使這個(gè)進(jìn)程徹底消失,。

wait

pid_t wait(int *statloc)

1進(jìn)程一旦調(diào)用了wait,就立即阻塞自己,,由wait自動(dòng)分析是否當(dāng)前進(jìn)程的某個(gè)子進(jìn)程已經(jīng)退出,,如果讓它找到了這樣一個(gè)已經(jīng)變成僵尸的子進(jìn)程,wait就會(huì)收集這個(gè)子進(jìn)程的信息,,并把它徹底銷毀后返回,;如果沒(méi)有找到這樣一個(gè)子進(jìn)程,wait就會(huì)一直阻塞在這里,,直到有一個(gè)出現(xiàn)為止,。

參數(shù)statloc用來(lái)保存被收集進(jìn)程退出時(shí)的一些狀態(tài),它是一個(gè)指向int類型的指針,。但如果我們對(duì)這個(gè)子進(jìn)程是如何死掉的毫不在意,,只想把這個(gè)僵尸進(jìn)程消滅掉,(事實(shí)上絕大多數(shù)情況下,,我們都會(huì)這樣想),,我們就可以設(shè)定這個(gè)參數(shù)為NULL,就象下面這樣:

pid = wait(NULL);

如果成功,,wait會(huì)返回被收集的子進(jìn)程的進(jìn)程ID,,如果調(diào)用進(jìn)程沒(méi)有子進(jìn)程,調(diào)用就會(huì)失敗,,此時(shí)wait返回-1,,同時(shí)errno被置為ECHILD

參數(shù)statloc

如果參數(shù)statloc的值不是NULL,,wait就會(huì)把子進(jìn)程退出時(shí)的狀態(tài)取出并存入其中,,這是一個(gè)整數(shù)值(int),指出了子進(jìn)程是正常退出還是被非正常結(jié)束的(一個(gè)進(jìn)程也可以被其他進(jìn)程用信號(hào)結(jié)束),,以及正常結(jié)束時(shí)的返回值,,或被哪一個(gè)信號(hào)結(jié)束的等信息。由于這些信息被存放在一個(gè)整數(shù)的不同二進(jìn)制位中,,所以用常規(guī)的方法讀取會(huì)非常麻煩,,人們就設(shè)計(jì)了一套專門的宏(macro)來(lái)完成這項(xiàng)工作,下面我們來(lái)學(xué)習(xí)一下其中最常用的兩個(gè):

● WIFEXITED(status)

這個(gè)宏用來(lái)指出子進(jìn)程是否為正常退出的,如果是,,它會(huì)返回一個(gè)非零值,。

(請(qǐng)注意,雖然名字一樣,,這里的參數(shù)status并不同于wait唯一的參數(shù)--指向整數(shù)的指針statloc,,而是那個(gè)指針?biāo)赶虻恼麛?shù),切記不要搞混了,。)

● WEXITSTATUS(status)

當(dāng)WIFEXITED返回非零值時(shí),,我們可以用這個(gè)宏來(lái)提取子進(jìn)程的返回值,如果子進(jìn)程調(diào)用exit(5)退出,,WEXITSTATUS (status)就會(huì)返回5,;如果子進(jìn)程調(diào)用exit(7)WEXITSTATUS(status)就會(huì)返回7,。請(qǐng)注意,,如果進(jìn)程不是正常退出的,也就是說(shuō),,WIFEXITED返回0,,這個(gè)值就毫無(wú)意義。

有興趣的讀者可以自己參閱Linux man pages去了解它們的用法,。

2進(jìn)程同步

有時(shí)候,,父進(jìn)程要求子進(jìn)程的運(yùn)算結(jié)果進(jìn)行下一步的運(yùn)算,或者子進(jìn)程的功能是為父進(jìn)程提供了下一步執(zhí)行的先決條件(如:子進(jìn)程建立文件,,而父進(jìn)程寫入數(shù)據(jù)),,此時(shí)父進(jìn)程就必須在某一個(gè)位置停下來(lái),等待子進(jìn)程運(yùn)行結(jié)束,,而如果父進(jìn)程不等待而直接執(zhí)行下去的話,,可以想見(jiàn),會(huì)出現(xiàn)極大的混亂,。這種情況稱為進(jìn)程之間的同步,,更準(zhǔn)確地說(shuō),這是進(jìn)程同步的一種特例,。進(jìn)程同步就是要協(xié)調(diào)好2個(gè)以上的進(jìn)程,,使之以安排好地次序依次執(zhí)行。

#include
#include
main()
{
pid_t pc, pr;
int status;
pc
=fork();
if(pc<0)
printf(
"Error occured on forking.n");
else if(pc==0){
/* 子進(jìn)程的工作 */
exit(
0);
}
else{
/* 父進(jìn)程的工作 */
pr
=wait(&status);
/* 利用子進(jìn)程的結(jié)果 */
}
}

waitpid

pid_t waitpid(pid_t pid,int *status,int options)

從本質(zhì)上講,,系統(tǒng)調(diào)用waitpidwait的作用是完全相同的,,但waitpid多出了兩個(gè)可由用戶控制的參數(shù)pidoptions,從而為我們編程提供了另一種更靈活的方式,。下面我們就來(lái)詳細(xì)介紹一下這兩個(gè)參數(shù):

● pid

從參數(shù)的名字pid和類型pid_t中就可以看出,,這里需要的是一個(gè)進(jìn)程ID,。但當(dāng)pid取不同的值時(shí),在這里有不同的意義,。

pid>0時(shí),,只等待進(jìn)程ID等于pid的子進(jìn)程,不管其它已經(jīng)有多少子進(jìn)程運(yùn)行結(jié)束退出了,,只要指定的子進(jìn)程還沒(méi)有結(jié)束,,waitpid就會(huì)一直等下去,。

pid=-1時(shí),,等待任何一個(gè)子進(jìn)程退出,沒(méi)有任何限制,,此時(shí)waitpidwait的作用一模一樣,。

pid=0時(shí),等待同一個(gè)進(jìn)程組中的任何子進(jìn)程,,如果子進(jìn)程已經(jīng)加入了別的進(jìn)程組,,waitpid不會(huì)對(duì)它做任何理睬。

pid<-1時(shí),,等待一個(gè)指定進(jìn)程組中的任何子進(jìn)程,,這個(gè)進(jìn)程組的ID等于pid的絕對(duì)值。

● options

options提供了一些額外的選項(xiàng)來(lái)控制waitpid,,目前在Linux中只支持WNOHANGWUNTRACED兩個(gè)選項(xiàng),,這是兩個(gè)常數(shù),可以用"|"運(yùn)算符把它們連接起來(lái)使用,,比如:

ret=waitpid(-1,NULL,WNOHANG | WUNTRACED);

如果我們不想使用它們,,也可以把options設(shè)為0,如:

ret=waitpid(-1,NULL,0);

如果使用了WNOHANG參數(shù)調(diào)用waitpid,,即使沒(méi)有子進(jìn)程退出,,它也會(huì)立即返回,不會(huì)像wait那樣永遠(yuǎn)等下去,。

WUNTRACED參數(shù),,由于涉及到一些跟蹤調(diào)試方面的知識(shí),加之極少用到,,有興趣的讀者可以自行查閱相關(guān)材料,。

可以看出,wait不就是經(jīng)過(guò)包裝的waitpid,。察看<內(nèi)核源碼目錄>/include/unistd.h文件349-352行就會(huì)發(fā)現(xiàn)以下程序段:

static inline pid_t wait(int * wait_stat)

{

return waitpid(-1,wait_stat,0);

}

返回值和錯(cuò)誤

waitpid的返回值比wait稍微復(fù)雜一些,,一共有3種情況:

當(dāng)正常返回的時(shí)候,waitpid返回收集到的子進(jìn)程的進(jìn)程ID,;

如果設(shè)置了選項(xiàng)WNOHANG,,而調(diào)用中waitpid發(fā)現(xiàn)沒(méi)有已退出的子進(jìn)程可收集,,則返回0

如果調(diào)用中出錯(cuò),,則返回-1,,這時(shí)errno會(huì)被設(shè)置成相應(yīng)的值以指示錯(cuò)誤所在;

當(dāng)pid所指示的子進(jìn)程不存在,,或此進(jìn)程存在,,但不是調(diào)用進(jìn)程的子進(jìn)程,waitpid就會(huì)出錯(cuò)返回,,這時(shí)errno被設(shè)置為ECHILD,;

#include
#include
#include
main()
{
pid_t pc, pr;
pc=fork();
if(pc<0) /* 如果fork出錯(cuò) */
printf(
"Error occured on forking.n");
else if(pc==0){ /* 如果是子進(jìn)程 */
sleep(
10); /* 睡眠10秒 */
exit(
0);
}
/* 如果是父進(jìn)程 */
do{
pr
=waitpid(pc, NULL, WNOHANG); /* 使用了WNOHANG參數(shù),waitpid不會(huì)在這里等待 */
if(pr==0){ /* 如果沒(méi)有收集到子進(jìn)程 */
printf(
"No child exitedn");
sleep(
1);
}
}
while(pr==0); /* 沒(méi)有收集到子進(jìn)程,,就回去繼續(xù)嘗試 */
if(pr==pc)
printf(
"successfully get child %dn", pr);
else
printf(
"some error occuredn");
}

更詳細(xì)參見(jiàn)[3],。

Linux中的進(jìn)程基本狀態(tài):

    1、執(zhí)行(R)狀態(tài):CPU正在執(zhí)行,,即進(jìn)程正在占用CPU,。

    2、就緒(W)狀態(tài):進(jìn)程已經(jīng)具備的執(zhí)行的一切條件,,正在等待分配CPU的處理時(shí)間片,。

3、停止(S)狀態(tài):進(jìn)程不能使用CPU,。

三個(gè)函數(shù):

fork();功能:創(chuàng)建一個(gè)新的進(jìn)程,。(fork()<0[出錯(cuò)]fork()==0[子進(jìn)程],、fork()>0[父進(jìn)程]

wait();功能:真正結(jié)束進(jìn)程(收尸),。

exec();功能:執(zhí)行外部程序。[4]

參考:

[1] http://blog.csdn.net/dai_weitao/archive/2007/08/01/1721184.aspx

[2] http://blog.csdn.net/upcuiling/archive/2006/04/26/678498.aspx

[3] http://blog.csdn.net/xjtuse_mal/archive/2007/05/31/1632185.aspx(詳細(xì))

[4] http://blog.csdn.net/stevexk/archive/2006/05/15/729215.aspx

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多