等待子进程结束wait()和waitpid()

父子进程有时需要简单的进程间同步,如父进程等待子进程的结束。

linux提供了以下两个等待函数:wait()waitpid().

需要包含头文件:

#include <sys/types.h>

#include <sys/wait.h>

1)  pid_t wait(int *status);

功能:等待任一子进程终止,如果子进程终止了,此函数会回收子进程的资源

调用wait函数的进程会被挂起(阻塞),直到它的一个子进程退出或收到一个不能被忽视的信号时才被唤醒。

若调用进程没有子进程或它的子进程已经结束,该函数立即返回。

参数:函数返回时,参数status中包含子进程退出时的状态信息。

子进程的退出信息在一个int中包含了多个字段,用宏定义可以取出其中的每个字段。

返回值:如果执行成功则返回子进程的进程号。出错返回-1,失败原因存在errno中。

取出子进程的退出信息:

>> WIFEXITED(status)

如果子进程是正常终止的,取出的字段值非零。

>>WEXITSTATUS(status)

返回子进程的退出状态,退出状态保存在status变量的8~16位。

在用此宏前应先用宏WIFEXITED判断子进程是否正常退出,正常退出才可以使用此宏。

fork3.c代码展示:

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

int main(){
    pid_t pid;
    pid = fork();
    if(pid < 0){
        printf("fork error.\n");
        return -1;
    }else if(pid == 0){
        int i = 0;
        for(i = 0;i < 3;i++){
            printf("this is child process.\n");
            sleep(1);
        }
        _exit(1);
    }else{
        int status = 0;
        wait(&status); //wait the end of child process
        if(WIFEXITED(status)){
            printf("child process return %d\n",WEXITSTATUS(status));
        }
        printf("this is father process.\n");
    }
    return 0;
}
编译和执行结果如下:


2)  pid_t waitpid(pid_t pid, int *status, int options);

功能:等待指定子进程终止,如果子进程终止了,此函数会回收子进程的资源。

返回值:如果执行成功则返回子进程ID。出错返回-1,失败原因存于errno中。

---- 从本质上讲,系统调用waitpid和wait的作用是完全相同的,但waitpid多出了两个可由用户控制的参数pid和options,从而为我们编程提供了另一种更灵活的方式。

pid:当参数pid取不同的值时,有不同的意义:

1> pid>0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。

2> pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样。

3> pid=0时,等待和该进程在同一个进程组中的任何子进程,如果某个子进程已经加入了别的进程组,waitpid不会对它做任何理睬。

4> pid<-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。

options:目前在Linux中只支持WNOHANG和WUNTRACED两个选项,可以用”|“运算符把它们连接起来使用,如:

         ret = waitpid(-1,NULL,WNOHANG|WUNTRACED);

WNOHANG,表示即使没有子进程退出,它也会立即返回,不会像wait那样永远等下去。

WUNTRACED,与跟踪调试有关,极少用到。

waitpid的返回值比wait稍微复杂一些,一共有3种情况:

>> 正常返回的时候,waitpid返回收集到的子进程的进程ID;

>> 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;

>> 调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在。例如:当pid所指示的子进程不存在,或此进程存在,但不是调用进程的子进程,waitpid就会出错返回,这时errno被设置为ECHILD。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值