wait函数和waitpid的使用和总结

wait和waitpid出现的原因
SIGCHLD
--当子进程退出的时候,内核会向父进程发送SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止)
--子进程退出时,内核将子进程置为僵尸状态,这个进程成为僵尸进程,它只保留最小的一些内核数据结构,以便父进程查询子进程的退出状态
--父进程查询子进程的退出状态可以用wait/waitpid函数

wait获取staus后检测处理
宏定义 描述
WIFEXITED(status) 如果进程子进程正常结束,返回一个非零值
WEXITSTATUS(status) 如果WIFEXITED非零,返回子进程退出码
WIFSIGNALED(status) 子进程因为捕获信号而终止,返回非零值
WTERMSIG(status) 如果WIFSIGNALED非零,返回信号代码
WIFSTOPPED(status) 如果进程被暂停,返回一个非零值
WSTOPSIG(status) 如果WIFSTOPPED非零,返回信号代码

wait系统调用在Linux函数库中的原型是:

#include <sys/types.h>   
#include <sys/wait.h>
pid_t wait(int *status)

进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经 退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就 会一直阻塞在这里,直到有一个出现为止。

参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就象下面这样

pid = wait(NULL);

waitpid系统调用在Linux函数库中的原型是:

函数功能:用来等待某个特定进程的结束

status如果不为空,会把状态信息写到它指向的位置
options允许改变waitpid的行为,最有用的一个选项是WNOHANG,它的作用是防止waitpid把调用者的执行挂起
返回值:成功返回等待子进程的pid,失败返回-1

#include <sys/types.h>  
#include <sys/wait.h> 
pid_t waitpid(pid_t pid,int *status,int options)
  • pid>0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。
  • pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样。
  • pid=0时,等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会对它做任何理睬。
  • pid<-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。

options提供了一些额外的选项来控制waitpid,目前在Linux中只支持WNOHANG和WUNTRACED两个选项,这是两个常数,可以用"|"运算符把它们连接起来使用,比如:

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

如果我们不想使用它们,也可以把options设为0,如:

ret=waitpid(-1,NULL,0);

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
 
int main(int arg,char *args[])
{
    pid_t pid=fork();
    if(pid==-1)
    {
        printf("fork() failed ! error message:%s\n",strerror(errno));
        return -1;
    }
    if(pid>0)
    {
        int status=0;
        printf("父进程\n");
        wait(&status);
        if(WIFEXITED(status))//WIFEXITED宏的释义: wait if exit ed
        {
            printf("子进程返回信息码:%d\n",WEXITSTATUS(status));
        }else if(WIFSIGNALED(status))
        {
            printf("子进程信号中断返回信息码:%d\n",WTERMSIG(status));
        }else if(WIFSTOPPED(status))
        {
            printf("子进程暂停返回信息码:%d\n",WSTOPSIG(status));
        }else
        {
            printf("其他退出信息!\n");
        }
    }else if(pid==0)
    {
        printf("i am child !\n");
        abort();
        //exit(100);
    }
    printf("game is over!\n");
    return 0;
}

wait()函数成功返回等待子进程的pid,失败返回-1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
 
int main(int arg, char *args[])
{
    pid_t pid = 0;
    int i = 0, ret = 0;
    for (i = 0; i < 10; i++)
    {
        pid = fork();
        if (pid == -1)
        {
            printf("fork() failed ! error message:%s\n", strerror(errno));
            return -1;
        }
        if (pid == 0)
        {
            printf("child haved run!\n");
            exit(0);
        }
    }
    while (1)
    {
        //wait()函数的返回值是子进程的pid
        ret = wait(NULL);
        printf("子进程pid=%d\n", ret);
        if (ret == -1)
        {
            //父进程wait()函数阻塞过程中,有可能被别的信号中断,需要做异常处理
            if (errno == EINTR)
            {
                continue;
            }
            break;
        }
    }
    printf("game is over!\n");
    return 0;
}

原文作者:cs_wu

原文地址:wait函数和waitpid的使用和总结 - cs_wu - 博客园(版权归原文作者所有,侵权留言联系删除)

如何写好简历项目,拿下高薪offer

c++项目实战课,完整项目实战内容,涵盖(基础架构,SPDK,内核,音视频,go云原生,Qt)的开发岗位

让你明白什么是专业。报名学习地址:

cpper面试自救指南​xxetb.xet.tech/s/3Bux46

项目详情:登录可看!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值