linux中waitpid及wait的用法

来源:互联网 发布:smali转换java 编辑:程序博客网 时间:2024/05/22 10:27

一.思维导图
    

两个函数都是用来等待子进程状态的改变,并获取相关的信息. 状态改变包括:
1)子进程终止
2)子进程被信号停止
3)子进程被信号恢复

二.实例讲解
 1.wait()

#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>#include <stdio.h> int main(){  pid_t pc, pr;  pc = fork();  if(pc<0){    printf("fork error\n");  }else if(pc == 0){    printf("this is child process.\n");  }else{    sleep(20);    printf("this is parent process.\n");  }   exit(0);}


[fl@linux1 c]$./wait
[fl@linux1 c]$ ps aux|grep wait

fl 8326 0.0 0.0 1600 276 pts/6 S+ 13:52 0:00 ./wait
fl 8327 0.0 0.0 0 0 pts/6 Z+ 13:52 0:00 [wait] <defunct>
fl 8330 2.0 0.0 4012 672 pts/5 R+ 13:52 0:00 grep wait
可以看出父进程sleep(20),没有调用wait()等待子进程终止,子进程就出会现运行结束无父进程清理自己的现象,从而成为Zombine进程.
如果在sleep(20)调用wait(NULL),运行结果就不会出现zombine进程。
fork()与wait()通常会配套使用。

2.waitpid()
   waitpid的原型是pid_t waitpid(pid_t pid, int *status, int options),本质上waitpid只是wait的封装
   参数pid的值有三种类型:
  pid>0,表示只等待进程ID等于pid的子进程
  pid=-1,等待任何一个子进程退出,此时于wait的作用无区别
  pid<-1,等待一个指定的进程组中的任何子进程,这个进程组的id等到于pid的绝对值。


wait(等待子进程中断或结束)
表头文件
     #include<sys/types.h>
     #include<sys/wait.h>
定义函数 pid_t wait (int * status);
函数说明:
    wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。

    如果在调用 wait()时子进程已经结束,则 wait()会立即返回子进程结束状态值。
    子进程的结束状态值会由参数 status 返回,而子进程的进程识别码也会一起返回。
   如果不在意结束状态值,则参数 status 可以设成 NULL。
     子进程的结束状态值请参考 waitpid( )     
如果执行成功则返回子进程识别码(PID) ,如果有错误发生则返回返回值-1。失败原因存于 errno 中。
pid_t  pid1;  int status=0;     
i=wait(&status);
i返回的是子进程的识别码;PID
status中存的是子进程的结束状态;可用WEXITSTATUS(status)得到子进程的exit(3)的状态,那么就是3;

waitpid(等待子进程中断或结束)
表头文件
      #include<sys/types.h>
      #include<sys/wait.h>
定义函数  pid_t waitpid(pid_t pid,int * status,int options);
函数说明:
    waitpid()会暂时停止目前进程的执行,直到有信号来到或子进程结束。
  如果在调用 wait()时子进程已经结束,则 wait()会立即返回子进程结束状态值。
    子进程的结束状态值会由参数 status 返回,而子进程的进程识别码也会一快返回。
   如果不在意结束状态值,则参数 status 可以设成 NULL。

  参数 pid 为欲等待的子进程识别码,其他数值意义如下:
     pid<-1 等待进程组识别码为 pid 绝对值的任何子进程。
     pid=-1 等待任何子进程,相当于 wait()。            
    pid=0     等待进程组识别码与目前进程相同的任何子进程。       
    pid>0     等待任何子进程识别码为 pid 的子进程。

    参数 option 可以为 0 或下面的 OR 组合:
    WNOHANG 如果没有任何已经结束的子进程则马上返回, 不予以等待。
    WUNTRACED 如果子进程进入暂停执行情况则马上返回,但结束状态不予以理会。

    子进程的结束状态返回后存于 status,底下有几个宏可判别结束情况:
    WIFEXITED(status)如果子进程正常结束则为非 0 值。
   WEXITSTATUS(status)取得子进程 exit()返回的结束代码,一般会先用 WIFEXITED 来判断是否正常结束才能使用此宏。
    WIFSIGNALED(status)如果子进程是因为信号而结束则此宏值为真
    WTERMSIG(status) 取得子进程因信号而中止的信号代码,一般会先用 WIFSIGNALED 来判断后才使用此宏。
    WIFSTOPPED(status) 如果子进程处于暂停执行情况则此宏值为真。一般只有使用 WUNTRACED 时才会有此情况。
    WSTOPSIG(status) 取得引发子进程暂停的信号代码,一般会先用 WIFSTOPPED 来判断后才使用此宏。
    如果执行成功则返回子进程识别码(PID) ,如果有错误发生则返回返回值-1。失败原因存于 errno 中。
   
  /*******    waitpid.c - Simple wait usage*********/#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>#include <stdio.h>#include <stdlib.h>int main( void ){    pid_t childpid;    int status;        childpid = fork();        if ( -1 == childpid )    {        perror( "fork()" );        exit( EXIT_FAILURE );    }    else if ( 0 == childpid )    {        puts( "In child process" );        sleep( 3 );//让子进程睡眠3秒,看看父进程的行为        printf("\tchild pid = %d\n", getpid());        printf("\tchild ppid = %d\n", getppid());        exit(EXIT_SUCCESS);    }    else     {        waitpid( childpid, &status, 0 );        puts( "in parent" );        printf( "\tparent pid = %d\n", getpid() );        printf( "\tparent ppid = %d\n", getppid()  );        printf( "\tchild process exited with status %d \n", status );    }    exit(EXIT_SUCCESS);}[root@localhost src]# gcc waitpid.c [root@localhost src]# ./a.out In child process        child pid = 4469        child ppid = 4468in parent        parent pid = 4468        parent ppid = 4379        child process exited with status 0 [root@localhost src]# 如果将上面“waitpid( childpid, &status, 0 );”行注释掉,程序执行效果如下:[root@localhost src]# ./a.out In child processin parent        parent pid = 4481        parent ppid = 4379        child process exited with status 1331234400 [root@localhost src]#   child pid = 4482        child ppid = 1子进程还没有退出,父进程已经退出了。


原创粉丝点击