#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid,int *status,int options)
|
pid
從參數的名字pid和類型pid_t中就可以看出,這裏需要的是一個進程ID。但當pid取不同的值時,在這裏有不同的意義。
- pid>0時,只等待進程ID等於pid的子進程,不管其它已經有多少子進程運行結束退出了,只要指定的子進程還沒有結束,waitpid就會一直等下去。
- pid=-1時,等待任何一個子進程退出,沒有任何限制,此時waitpid和wait的作用一模一樣。
- pid=0時,等待同一個進程組中的任何子進程,如果子進程已經加入了別的進程組,waitpid不會對它做任何理睬。
- pid<-1時,等待一個指定進程組中的任何子進程,這個進程組的ID等於pid的絕對值。
options提供了一些額外的選項來控制waitpid,目前在Linux中只支持WNOHANG和WUNTRACED兩個選項,這是兩個常數,可以用"|"運算符把它們連接起來使用,比如:
ret=waitpid(-1,NULL,WNOHANG | WUNTRACED);
|
ret=waitpid(-1,NULL,0);
|
而WUNTRACED參數,由於涉及到一些跟蹤調試方面的知識,加之極少用到,這裏就不多費筆墨了,有興趣的讀者可以自行查閱相關材料。
wait不就是經過包裝的waitpid嗎?沒錯,察看<內核源碼目錄>/include/unistd.h文件349-352行就會發現以下程序段:
static inline pid_t wait(int * wait_stat)
{
return waitpid(-1,wait_stat,0);
}
|
waitpid的返回值比wait稍微複雜一些,一共有3種情況:
- 當正常返回的時候,waitpid返回收集到的子進程的進程ID;
- 如果設置了選項WNOHANG,而調用中waitpid發現沒有已退出的子進程可收集,則返回0;
- 如果調用中出錯,則返回-1,這時errno會被設置成相應的值以指示錯誤所在;
當pid所指示的子進程不存在,或此進程存在,但不是調用進程的子進程,waitpid就會出錯返回,這時errno被設置爲ECHILD;
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
main()
{
pid_t pc, pr;
pc=fork();
if(pc<0)
printf("Error occured on forking.\n");
else if(pc==0)
{
sleep(4);
exit(0);
}
do
{
pr=waitpid(pc, NULL, WNOHANG);
if(pr==0)
{
printf("No child exited\n");
sleep(1);
}
}while(pr==0);
if(pr==pc)
printf("successfully release child %d\n", pr);
else
printf("some error occured\n");
}
|
編譯並運行:
$ cc waitpid.c -o waitpid
$ ./waitpid
No child exited
No child exited
No child exited
No child exited
successfully release child 1526
|
父進程經過4次失敗的嘗試之後,終於收集到了退出的子進程。
因爲這只是一個例子程序,不便寫得太複雜,所以我們就讓父進程和子進程分別睡眠了4秒鐘和1秒鐘,代表它們分別作了4秒鐘和1秒鐘的工作。父子進程都有工作要做,父進程利用工作的簡短間歇察看子進程的是否退出,如退出就收集它.這樣的話,既不影響父進程的工作,也可以消除殭屍進程.
最後 不管是 wait 還是waitpid函數都有個參數來反映子進程的結束狀態,底下有幾個宏可判別結束情況,參數當然是指針指向的那個:
WIFEXITED(status)如果子進程正常結束則爲非0 值。
WEXITSTATUS(status)取得子進程exit()返回的結束代碼,一般會先用WIFEXITED 來判斷是否正常結束才能使用此宏。
WIFSIGNALED(status)如果子進程是因爲信號而結束則此宏值爲真
WTERMSIG(status) 取得子進程因信號而中止的信號代碼,一般會先用WIFSIGNALED 來判斷後才使用此宏。
WIFSTOPPED(status) 如果子進程處於暫停執行情況則此宏值爲真。一般只有使用WUNTRACED 時纔會有此情況。
WSTOPSIG(status) 取得引發子進程暫停的信號代碼,一般會先用WIFSTOPPED 來判斷後才使用此宏。
返回值
如果執行成功則返回子進程識別碼(PID),如果有錯誤發生則返回
-1。失敗原因存於errno 中。
轉自:http://blog.sina.com.cn/s/blog_602a39250100xfxx.html