linuxwait()函數_第1頁
linuxwait()函數_第2頁
linuxwait()函數_第3頁
linuxwait()函數_第4頁
linuxwait()函數_第5頁
全文預覽已結束

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、在UNIX系統(tǒng)中,一個進程結束了,但是他的父進程沒有等待(調用wait/waitpid)他,那么他將變成一個僵尸進程.但是如果該進程的父進程已經先結束了,那么該進程就不會變成僵尸進程,因為每個進程結束的時候,系統(tǒng)都會掃描當前系統(tǒng)中所運行的所有進程,看有沒有哪個進程是剛剛結束的這個進程的子進程,如果是的話,就由Init來接管他,成為他的父進程一個進程在調用exit命令結束自己的生命的時候,其實它并沒有真正的被銷毀,而是留下一個稱為僵尸進程(Zombie)的數據結構(系統(tǒng)調用exit,它的作用是使進程退出,但也僅僅限于將一個正常的進程變成一個僵尸進程,并不能將其完全銷毀)僵尸進程的危害由于子進程的

2、結束和父進程的運行是一個異步過程,即父進程永遠無法預測子進程到底什么時候結束.那么不會因為父進程太忙來不及waid子進程,或者說不知道子進程什么時候結束,而丟失子進程結束時的狀態(tài)信息呢?不會.因為UNIX提供了一種機制可以保證只要父進程想知道子進程結束時的狀態(tài)信息,就可以得到.這種機制就是:在每個進程退出的時候,內核釋放該進程所有的資源,包括打開的文件,占用的內存等.但是仍然為其保留一定的信息(包括進程號theprocessID,退出狀態(tài)theterminationstatusoftheprocess,運行時間theamountofCPUtimetakenbytheprocess等),直至U父

3、進程通過wait/waitpid來取時才釋放.但這樣就導致了問題,如果你進程不調用wait/waitpid的話,那么保留的那段信息就不會釋放,其進程號就會一定被占用,但是系統(tǒng)所能使用的進程號是有限的,如果大量的產生僵死進程,將因為沒有可用的進程號而導致系統(tǒng)不能產生新的進程.此即為僵尸進程的危害,應當避免.僵尸進程的避免父進程通過wait和waitpid等函數等待子進程結束,這會導致父進程掛起如果父進程很忙,那么可以用signal函數為SIGCHLD安裝handler,因為子進程結束后,父進程會收到該信號,可以在handler中調用wait回收如果父進程不關心子進程什么時候結束,那么可以用sig

4、nal(SIGCHLD,SIG_IGN)通知內核,自己對子進程的結束不感興趣,那么子進程結束后,內核會回收,并不再給父進程發(fā)送信號還有一些技巧,就是fork兩次,父進程fork一個子進程,然后繼續(xù)工作,子進程fork一個孫進程后退出,那么孫進程被init接管,孫進程結束后,init會回收。不過子進程的回收還要自己做。下面就是Stevens給的采用兩次folk避免僵尸進程的示例.3、僵尸進程的處理:它需要它的父進程來為它收尸,如果他的父進程沒安裝SIGCHLD信號處理函數調用wait或waitpid()等待子進程結束,又沒有顯式忽略該信號,那么它就一直保持僵尸狀態(tài);存在的問題:如果父進程是一個循

5、環(huán),不會結束,那么子進程就會一直保持僵尸狀態(tài),這就是為什么系統(tǒng)中有時會有很多的僵尸進程,系統(tǒng)的性能可能會收至影響。*如果這時父進程結束了,那么init進程自動會接手這個子進程,為它收尸,它還是能被清除的。4、子進程結束后為什么要進入僵尸狀態(tài)?*因為父進程可能要取得子進程的退出狀態(tài)等信息。5、僵尸狀態(tài)是每個子進程比經過的狀態(tài)嗎?是的。*任何一個子進程(init除外)在exit()之后,并非馬上就消失掉,而是留下一個稱為僵尸進程(Zombie)的數據結構,等待父進程處理。這是每個子進程在結束時都要經過的階段。如果子進程在exit()之后,父進程沒有來得及處理,這時用ps命令就能看到子進程的狀態(tài)是“

6、Z”。如果父進程能及時處理,可能用ps命令就來不及看到子進程的僵尸狀態(tài),但這并不等于子進程不經過僵尸狀態(tài)。*如果父進程在子進程結束之前退出,則子進程將由init接管。init將會以父進程的身份對僵尸狀態(tài)的子進程進行處理。6、如何查看僵尸進程:$ps-el其中,有標記為Z的進程就是僵尸進程S代表休眠狀態(tài);D代表不可中斷的休眠狀態(tài);R代表運行狀態(tài);Z代表僵死狀態(tài);T代表停止或跟蹤狀態(tài)wait系統(tǒng)調用系統(tǒng)中的僵尸進程都要由wait系統(tǒng)調用來回收,下面就通過實戰(zhàn)看一看wait的具體用法:wait的函數原型是:#include/*提供類型pid_t的定義*/#includepid_twait(int*s

7、tatus);進程一旦調用了wait,就立即阻塞自己,由wait自動分析是否當前進程的某個子進程已經退出,如果讓它找到了這樣一個已經變成僵尸的子進程,wait就會收集這個子進程的信息,并把它徹底銷毀后返回;如果沒有找到這樣一個子進程,wait就會一直阻塞在這里,直到有一個出現為止。參數status用來保存被收集進程退出時的一些狀態(tài),它是一個指向int類型的指針。但如果我們對這個子進程是如何死掉的毫不在意,只想把這個僵尸進程消滅掉,(事實上絕大多數情況下,我們都會這樣想),我們就可以設定這個參數為NULL,就象下面這樣:pid=wait(NULL);如果成功,wait會返回被收集的子進程的進程I

8、D,如果調用進程沒有子進程,調用就會失敗,此時wait返回-1,同時errno被置為ECHILD。下面就讓我們用一個例子來實戰(zhàn)應用一下wait調用:/*wait1.c*/#include#include#include#include#include#includeintmain()pid_tpc,pr;pc=fork();if(pc0)/*子進程正常返回*/printf(Icatchedachildprocesswithpidof%dn,pr);else/*出錯*/printf(error:%sn.n,strerror(errno);exit(0);編譯并運行:$gccwait1.c-owa

9、it1$./wait1Iamchildprocesswithpid2351Nowinparentprocess,pid=2350Iamwaitingchildprocesstoexit.Icatchedachildprocesswithpidof2351可以明顯注意到,在第2行結果打印出來前有10秒鐘的等待時間,這就是我們設定的讓子進程睡眠的時間,只有子進程從睡眠中蘇醒過來,它才能正常退出,也就才能被父進程捕捉到。其實這里我們不管設定子進程睡眠的時間有多長,父進程都會一直等待下去,讀者如果有興趣的話,可以試著自己修改一下這個數值,看看會出現怎樣的結果。如果參數status的值不是NULL,wa

10、it就會把子進程退出時的狀態(tài)取出并存入其中,這是一個整數值(int),指出了子進程是正常退出還是被非正常結束的(一個進程也可以被其他進程用信號結束,我們將在以后的文章中介紹),以及正常結束時的返回值,或被哪一個信號結束的等信息。由于這些信息被存放在一個整數的不同二進制位中,所以用常規(guī)的方法讀取會非常麻煩,人們就設計了一套專門的宏(macro)來完成這項工作,下面我們來學習其中最常用的兩個:1,WIFEXITED(status)這個宏用來指出子進程是否為正常退出的,如果是,它會返回一個非零值。(請注意,雖然名字一樣,這里的參數status并不同于wait唯一的參數-指向整數的指針status,而

11、是那個指針所指向的整數,切記不要搞混了。2,WEXITSTATUS(status)當WIFEXITED返回非零值時,我們可以用這個宏來提取子進程的返回值,如果子進程調用exit(5)退出,WEXITSTATUS(status)就會返回5;如果子進程調用exit(7),WEXITSTATUS(status)就會返回7。請注意,如果進程不是正常退出的,也就是說,WIFEXITED返回0,這個值就毫無意義。下面通過例子來實戰(zhàn)一下我們剛剛學到的內容:/*wait2.c*/#include#include#includeintmain()intstatus;pid_tpc,pr;pc=fork();if

12、(pc0)/*如果出錯*/printf(erroroccured.n);elseif(pc=0)/*子進程*/printf(Thisischildprocesswithpidof%d.n,getpid();exit(3);/*子進程返回3*/else/*父進程*/pr=wait(&status);if(WIFEXITED(status)/*如果WIFEXITED返回非零值*/printf(Thechildprocess%dexitnormally.n,pr);printf(thereturncodeis%d.n,WEXITSTATUS(status);else/*如果WIFEXITED返回零*/printf(Thechildprocess%dexitabnormally.n,pr);exit(0);編譯并運行:$gccwait2.c-owait2$./wait2This

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論