天天看點

Linux系統程式設計

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