Linux多进程--wait/waitpid

等待子进程状态改变函数wait

函数原型:pid_t wait(int *status);
头文件:#include <sys/types.h>	#include <sys/wait.h>
输入参数:
	status: int型指针,用于获取子进程状态发生改变时,返回的状态值。
返回值:pid_t是一个宏定义,其实质是int被定义在#include <sys/types.h>

函数说明

调用wait函数将会使当前进程处于阻塞状态,直到有一个子进程的状态发生改变,当子进程接收到某个信号停止运行或者从stop状态转为继续执行时,被认为子进程的状态发生改变。
在子进程停止运行的状态下,执行wait函数将会使系统释放与子进程相关联的系统资源,如果不执行该函数,则子进程将会处于“僵停”状态,成为僵尸进程。
如果子进程的状态已经发生了改变(比如子进程已经停止运行)。调用wait函数将会立即返回。
如果函数执行成功返回进程PID,如果函数执行失败,则返回-1

等待指定子进程状态改变函数waitpid

函数原型:pid_t wait(pid_t pid,int *status,int options);
头文件:#include <sys/types.h>	#include <sys/wait.h>
输入参数:
	pid: 指定的子进程pid
	status: int型指针,用于获取子进程状态发生改变时,返回的状态值。
	options: 选项,
返回值:pid_t是一个宏定义,其实质是int被定义在#include <sys/types.h>

函数说明

waitpid函数的调用将阻塞调用进程的执行,直到pid参数指定的子进程状态发生了改变,默认情况下,waitpid只等待子进程的终止,但是这个行为可以通过options参数进行修改。

参数pid如何指定特定的进程或进程的集合

参数pid本质上是int型参数,其值可以分为四类表示,具体描述如下:

  1. pid值小于-1,表示等待pid的绝对值与该参数相等的进程的所有子进程状态发生改变,比如传入的pid = -100 则调用该函数,系统所有pid值为100的进程的子进程状态发生改变,都会导致函数返回,停止阻塞。

  2. pid值等于-1,表示等待当前进程的所有子进程状态发生改变。

  3. pid值等于0,表示等待和调用该函数的进程拥有同一个进程组ID的进程状态发生改变(比如拥有同一个父进程的进程)。

  4. pid值大于0,表示表示指定的进程的pid。

参数options的使用

参数options的值可以通过以下几个常量的值进行或运算取得,其字段名称以及具体含义如下:

  1. WNOHANG: 通知内核在没有已终止进程项时不要阻塞。即如果没有子进程已经终止,则立即返回。
  2. WUNTRACED:若实现支持作业控制,而pid指定的任一子进程已经暂停,且其状态尚未报告,则返回其状态。
  3. WCONTINUED:如果进程从stop状态变为继续执行状态时,返回该状态。

如果waitpid函数执行成功,返回状态发生改变的进程PID,如果WNOHANG被设置,并且同时有多个进程已经退出了,返回0,如果函数执行失败返回-1

错误类型

wait函数和waitpid函数错误状态保持一致,其错误信息由status字段获取。函数执行失败的错误类型的具体表述如下:

  1. ECHILD:对于wait函数返回该错误,表示当前没有任何未被释放的子进程。对于waitpid函数返回该错误,表示通过pid参数指定的进程不存在,或者该pid是当前调用进程的PID。
  2. EINTR:当前没有设置WNOHANG状态,并且在函数执行过程中捕获到了SIGCHILD信号或者是其他不被阻塞的信号。
  3. EINVAL:选项字段设置的状态无效。

官方例程

	#include <sys/wait.h>
   #include <stdlib.h>
   #include <unistd.h>
   #include <stdio.h>

   int main(int argc, char *argv[])
   {
       pid_t cpid, w;
       int status;

       cpid = fork();
       if (cpid == -1) {
           perror("fork");
           exit(EXIT_FAILURE);
       }

       if (cpid == 0) {            /* Code executed by child */
           printf("Child PID is %ld\n", (long) getpid());
           if (argc == 1)
               pause();                    /* Wait for signals */
           _exit(atoi(argv[1]));

       } else {                    /* Code executed by parent */
           do {
               w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);
               if (w == -1) {
                   perror("waitpid");
                   exit(EXIT_FAILURE);
               }

               if (WIFEXITED(status)) {
                   printf("exited, status=%d\n", WEXITSTATUS(status));
               } else if (WIFSIGNALED(status)) {
                   printf("killed by signal %d\n", WTERMSIG(status));
               } else if (WIFSTOPPED(status)) {
                   printf("stopped by signal %d\n", WSTOPSIG(status));
               } else if (WIFCONTINUED(status)) {
                   printf("continued\n");
               }
           } while (!WIFEXITED(status) && !WIFSIGNALED(status));
           exit(EXIT_SUCCESS);
       }
   }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值