wait和waitpid函式總結

2021-07-15 17:44:38 字數 3569 閱讀 8730

wait和waitpid兩個函式的功能:

1.防止產生殭屍程序

2.根據需求,先讓父程序掛起等待子程序結束後,再執行,實現程序的同步。

殭屍程序:乙個程序使用fork建立子程序,如果子程序退出,而父程序並沒有呼叫wait或waitpid獲取子程序的狀態資訊,那麼子程序的程序描述符仍然儲存在系統中。這種程序稱之為僵死程序。

如果程序不呼叫wait / waitpid的話, 那麼保留的那段資訊就不會釋放,其程序號就會一直被占用,但是系統所能使用的程序號是有限的,如果大量的產生僵死程序,將因為沒有可用的程序號而導致系統不能產生新的程序. 此即為殭屍程序的危害,應當避免。

wait函式:

函式原型:

#include

#include

pid_t wait(int *status)

程序一旦呼叫了wait,就立即阻塞自己,由wait自動分析是否當前程序的某個子程序已經退出,如果讓它找到了這樣乙個已經變成殭屍的子程序,wait就會收集這個子程序的資訊,並把它徹底銷毀後返回;如果沒有找到這樣乙個子程序,wait就會一直阻塞在這裡,直到有乙個出現為止。

引數status用來儲存被收集程序退出時的一些狀態,它是乙個指向int型別的指標。

引數status:

如果引數status的值不是null,wait就會把子程序退出時的狀態取出並存入其中,這是乙個整數值(int),指出了子程序是正常退出還是被非正常結束的,以及正常結束時的返回值,或被哪乙個訊號結束的等資訊。由於這些資訊被存放在乙個整數的不同二進位制位中,所以用常規的方法讀取會非常麻煩,人們就設計了一套專門的巨集(macro)來完成這項工作:

1.wifexited(status) 這個巨集用來指出子程序是否為正常退出的,如果是,它會返回乙個非零值。

2. wexitstatus(status) 當wifexited返回非零值時,我們可以用這個巨集來提取子程序的返回值,如果子程序呼叫exit(5)退出,wexitstatus(status) 就會返回5;如果子程序呼叫exit(7),wexitstatus(status)就會返回7。

但如果我們對這個子程序是如何死掉的毫不在意,只想把這個殭屍程序消滅掉,(事實上絕大多數情況下,我們都會這樣想),我們就可以設定這個引數為null,就象下面這樣:

pid = wait(null);

3.wifsignaled(status)若為異常結束子程序返回的狀態,則為真;對於這種情況可執行wtermsig(status),取使子程序結束的訊號編號。

4.wtermsig(status) 取得子程序因訊號而中止的訊號**,一般會先用 wifsignaled 來判斷後才使用此巨集。

5.wifstopped(status) 若為當前暫停子程序返回的狀態,則為真;對於這種情況可執行wstopsig(status),取使子程序暫停的訊號編號。

6.wstopsig(status) 取得引發子程序暫停的訊號**,一般會先用 wifstopped 來判斷後才使用此巨集。

如果成功,wait會返回被收集的子程序的程序id,如果呼叫程序沒有子程序,呼叫就會失敗,此時wait返回-1,同時errno被置為echild。

waitpid函式:

函式原型:

#include

#include

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

從本質上講,系統呼叫waitpid和wait的作用是完全相同的,但waitpid多出了兩個可由使用者控制的引數pid和options,從而為我們程式設計提供了另一種更靈活的方式。下面我們就來詳細介紹一下這兩個引數:

引數pid:

從引數的名字pid和型別pid_t中就可以看出,這裡需要的是乙個程序id。但當pid取不同的值時,在這裡有不同的意義。

pid>0時,只等待程序id等於pid的子程序,不管其它已經有多少子程序執行結束退出了,只要指定的子程序還沒有結束,waitpid就會一直等下去。 

pid=-1時,等待任何乙個子程序退出,沒有任何限制,此時waitpid和wait的作用一模一樣。

pid=0時,等待同乙個程序組中的任何子程序,如果子程序已經加入了別的程序組,waitpid不會對它做任何理睬。 

pid<-1時,等待乙個指定程序組中的任何子程序,這個程序組的id等於pid的絕對值。 

引數options:

ptions提供了一些額外的選項來控制waitpid,目前在linux中只支援wnohang和wuntraced兩個選項,這是兩個常數,可以用"|"運算子把它們連線起來使用,比如:

ret=waitpid(-1,null,wnohang | wuntraced);

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

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

如果使用了wnohang引數呼叫waitpid,即使沒有子程序退出,它也會立即返回,不會像wait那樣永遠等下去。

wuntraced 若子程序進入暫停狀態,則馬上返回,但子程序的結束狀態不予以理會。

wcontinued //如果停止了的程序由於sigcont訊號的到來而繼續執行,呼叫將返回。

waitpid的返回值比wait稍微複雜一些,一共有3種情況:

當正常返回的時候,waitpid返**集到的子程序的程序id; 

如果設定了選項wnohang,而呼叫中waitpid發現沒有已退出的子程序可收集,則返回0; 

如果呼叫中出錯,則返回-1,這時errno會被設定成相應的值以指示錯誤所在;

wait函式和waitpid函式

1.殭屍程序 說明子程序結束但是沒有完全釋放記憶體 在核心中的task struct沒有釋放 該程序就會成為殭屍程序 當殭屍程序的父程序結束後就會被init程序 1號程序 接管,最終被 殭屍程序的危害 如果你不處理殭屍程序的話,那麼保留的那段資訊就不會釋放,其程序號就會一定被占用,但是系統所能使用的...

wait函式和waitpid函式

1 wait函式 當乙個程序結束時,會關閉所有的檔案描述符,釋放所有的記憶體空間,但依然儲存其pcb,核心在pcb中儲存著一些資訊。如果是正常退出,則會儲存退出狀態。如果是異常終止,則儲存是哪個訊號終止了該程序。父程序通過呼叫wait 或者waitpid 函式,來獲取這些資訊,之後徹底清除改程序。只...

wait和 wait pid函式用法

wait和 wait pid函式用法 wait的函式原型是 i nclude 提供型別pid t的定義 i nclude pid t wait int status 程序一旦呼叫了wait,就立即阻塞自己,由wait自動分析是否當前程序的某個子程序已經退出,如果讓它找到了這樣乙個已經變成殭屍的子程序...