wait()和waitpid()
函數說明
wait()函數用于使父程序(也就是調用wait()的程序)阻塞,直到一個子程序結束或者該程序接收到了一個指定的信号為止。如果該父程序沒有子程序或者它的子程序已經結束,則wait()函數就會立即傳回。
waitpid()的作用和wait()一樣,但它并不一定要等待第一個終止的子程序(它可以指定需要等待終止的子程序),它還有若幹選項,如可提供一個非阻塞版本的 wait()功能,也能支援作業控制。實際上,wait()函數隻是 waitpid()函數的一個特例,在Linux
内部實作 wait()函數時直接調用的就是waitpid()函數。
函數格式
下圖為wait()函數的格式
下圖為waitpid()函數的格式
基礎實驗
實驗1
本實驗中首先使用fork()建立一個子程序,然後讓其子程序暫停5s(使用了sleep()函數)。接下來對原有的父程序使用waitpid()函數,并使用參數WNOHANG是該父程序不會阻塞。若有子程序退出,則waitpid()傳回子程序号;若沒有子程序退出,則waitpid()傳回0,并且父程序每隔1s循環判斷一次。該程式的流程圖如下:
程式源代碼我上傳到網站,可以免費下載下傳waitpid.c檔案,
下載下傳檔案後,使用指令:gcc waitpid.c -o waitpid
然後執行指令:./waitpid 結果如下圖;
從輸出結果就可以看出程式的執行流程。先執行一次父程序,父程序睡眠1s,此時執行子程序,然後子程序睡眠5秒;接着再執行父程序監聽。哎喲我去我不分析流程了,怕再說迷糊了。
實驗2
本實驗使用函數wait(),同實驗2一樣,也是先用fork()建立一個子程序,然後讓子程序暫停5s。接下來對原有的父程序使用wait()函數。不同的是,wait()函數會使得父程序阻塞,通過本實驗的結果就可以看出。代碼如下:
執行結果如下圖
我建議你親自實驗一下,能很明顯的看出不同。wait.c檔案
/* wait.c檔案*/
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
int main()
{
pid_t pc,pr;
pc=fork();/*建立新子程序*/
if(pc<0)
{
printf("Error fork\n");
}
else if(pc==0) /* 子程序 */
/*子程序暫停5s*/
printf("I am the child progress.I am going sleep!\n");
sleep(5);
/*子程序正常退出*/
printf("I am the child progress.I am going exit!\n");
exit(0);
else /*父程序*/
pr=wait(NULL);
if(pr<0)
{
printf("Some error occured.\n");
}
printf("I am the father progress.I get child exit code:%d\n",pr);
}
/* waitpid.c */
pc=fork();/*建立新的子程序*/
if(pc<0) /*出錯處理*/
else if(pc==0) /*子程序*/
else /*父程序*/
/*循環測試子程序是否退出*/
do
/*調用waitpid(),且父程序不阻塞*/
pr=waitpid(pc,NULL,WNOHANG);
/*若子程序還未退出,則父程序暫停1s*/
if(pr==0) /*傳回0說明子程序沒有退出*/
{
printf("I am the father progress.The child process has not exited\n");
sleep(1);
}
} while(pr==0);
/*若發現子程序退出,列印出相應情況*/
if(pr==pc)
printf("I am the father progress.I get child exit code:%d\n",pr);
else