进程非阻塞等待

waitpid函数的options参数

当options为0时,表示父进程为阻塞等待,阻塞等待是什么意思呢?
当options为WNOHANG(1)时,表示父进程为非阻塞等待,这又是什么意思?

WNOHANG:Linux底层就是C语言写的,而OS自己提供的接口函数,其实就是C语言函数,系统提供的一般大写的标记位WNOHANG,其实是宏定义!
WNOHANG——>wait no hang,一般别人说夯住了,其实就是这个进程没有被CPU调度(阻塞或者正等待调度),所以说,wait no 夯就是非阻塞等待。

阻塞等待就是,操作系统检测到子进程没有结束时,父进程就阻塞挂起,然后一直等到子进程运行结束父进程就被唤醒。
非阻塞等待就是,如果子进程没有退出,waitpid这个系统调用就会立马返回,而不用一直等待着子进程结束。

不妨看一下waitpid伪代码:
在这里插入图片描述
所以进程阻塞,本质还是在函数内部阻塞!
当父进程被唤醒的时候,还是从被挂起的地方开始执行。
那这个非阻塞等待有啥用呢,当父进程检测到子进程还在运行时,waitpid函数就会直接退出,父进程就可以去执行其他的任务,隔段时间再调用waitpid函数,只要子进程没结束父进程就去执行别的任务,只要子进程结束了父进程就可以释放掉僵尸进程,这就是基于非阻塞调用的轮询检测方案

代码示例:

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

typedef void (*handler_t)();
std::vector<handler_t> handlers;

void fun_1()
{
    printf("这是任务一\n");
}

void fun_2()
{
    printf("这是任务二\n");
}

void Load()
{
    handlers.push_back(fun_1);
    handlers.push_back(fun_2);
}
int main()
{
    pid_t id = fork();
    if(id == 0)
    {
        int cnt=5;
        while(cnt)
        {
            printf("我是子进程:cnt:%d  pid:%d  ppid%d\n",cnt--,getpid(),getppid());
            sleep(1);
        }

    }

    else 
    {
        printf("我是父进程:pid:%d  ppid:%d\n",getpid(),getppid());
        
        int status = 0;
        pid_t ret=waitpid(id,&status,WNOHANG);
        
        int quit=0;
        while(!quit)
        {
            ret=waitpid(id,&status,WNOHANG);
            if(ret>0)
            {
                //等待成功,子进程退出
                if(WIFEXITED(status))
                {
                     printf("父进程等待子进程退出成功:退出码:%d\n",WEXITSTATUS(status));
                }
                quit=1;
            }

            else if(ret==0)
            {
                  printf("子进程暂时还没有退出,父进程可以处理其他任务\n");
                if(handlers.empty()){
                    Load();
                }
                int i=0;
                for(i=0;i<handlers.size();i++)
                {
                   handlers[i](); 
                }
            }

            else 
            {
                printf("wait fail\n");
                quit=1;
            }
            sleep(1);
        }
    }

    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值