当前位置: 首页 > news >正文

阻塞与非阻塞等待非阻塞轮询

目录

阻塞等待(Blocking Wait)

非阻塞等待(Non-blocking Wait)

非阻塞轮询

总结


进程等待所使用 waitpid 函数,有一个 options 参数,waitpid 函数的第三个参数用于指定父进程的等待方式

  • 0:默认等待,阻塞直到一个子进程结束。
  • WNOHANG非阻塞等待,如果没有任何子进程结束,则立即返回 0,不阻塞当前进程.若正常结束,则返回该子进程的 ID。
  • WUNTRACED:报告被跟踪的子进程(即使它们尚未停止)。
  • WCONTINUED:报告被继续执行的子进程(即被 SIGCONT 信号继续执行)
阻塞等待(Blocking Wait)

 阻塞等待意味着父进程会一直等待,直到子进程结束或出现错误为止。
通常使用 wait() 或带有默认选项的 waitpid() 函数实现(即 参数 options = 0):waitpid(pid, &status, 0);

非阻塞等待(Non-blocking Wait)

非阻塞等待允许父进程在没有子进程结束的情况下继续执行其他任务。如果子进程未退出,父进程会直接读取子进程的状态并返回,然后接着执行后面的语句,不会等待子进程退出
通常使用带有 WNOHANG 选项的 waitpid() 函数实现(即 参数 options = WNOHANGwaitpid(pid, &status, WNOHANG);

非阻塞轮询

轮询是指父进程在非阻塞式状态的前提下,以循环方式不断的对子进程进行进程等待,直到子进程退出。

例如,父进程可以隔一段时间调用一次waitpid函数,若是等待的子进程尚未退出,则父进程可以先去做一些其他事,过一段时间再调用waitpid函数读取子进程的退出信息:

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

void task1() {
    printf("task1 is running...\n");
}

void task2() {
    printf("task2 is runnning...\n");
}

int main() {
    int id = fork();
    if(id == -1) {
        printf("fork error\n");
        exit(-1);
    } else if(id == 0) {  //子进程
        int cnt = 5;
        while(cnt--) {
            printf("子进程, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt);
            sleep(1);
        }
        exit(1);
    } else {  //父进程
        int status = 0;
        while(1) {  //轮询
            pid_t ret = waitpid(id, &status, WNOHANG);  //非阻塞式等待
            if(ret == -1) {
                printf("wait fail\n");  //调用失败
                exit(1);
            } else if(ret == 0){  //调用成功,但子进程未退出
                printf("wait success, but child process not exit\n");
                task1();  //执行其他命令
                task2();
            } else {  //调用成功,子进程退出
                printf("wait success, and child exited\n");
                break;
            }
            sleep(1);
        }

        if(WIFEXITED(status)) {  //正常退出
            printf("exit code:%d\n", WEXITSTATUS(status));
        } else {  //异常终止
            printf("exit signal:%d\n",(status & 0x7f));
        }
        
    }
    return 0;
}

 运行结果就是,父进程每隔一段时间就去查看子进程是否退出,若未退出,则父进程先去忙自己的事情,过一段时间再来查看,直到子进程退出后读取子进程的退出信息。

总结

阻塞等待:先等你,我再继续

非阻塞等待:不等你,我继续做自己的事

非阻塞轮询:不等你,我继续做自己的事,期间不断看看你行没行

相关文章:

  • 代码,Java Maven项目打包遇到的环境问题
  • 针对OPPO A5(PBAM00)在锁屏界面屏幕无法滑动的问题.
  • STM32 HAL库 HC-05蓝牙通信实现
  • 《嵌入式系统原理》一些题目
  • Mysql5.7配置文件
  • StickyNotes,简单便签超实用
  • 变点分组法是一种时序数据处理与分段分析的方法
  • 聊聊Spring AI的Prompt
  • 20250414| AI:RAG多路召回和融合重排序技术
  • Android Studio 在 Windows 上的完整安装与使用指南
  • TreeMap和HashMap的区别
  • CST1020.基于Spring Boot+Vue汽车租赁管理系统
  • Neo4j GDS-10-neo4j GDS 库中相似度算法介绍
  • 自用:在使用SpringBoot做学生信息管理系统时遇到的问题
  • Npfs!NpFsdCreate函数分析之从NpCreateClientEnd函数分析到Npfs!NpSetConnectedPipeState
  • MySQL表的增删改查进阶版
  • Java学习——day29(并发控制高级工具与设计模式)
  • JavaWeb-04-Web后端基础(SpringBootWeb、HTTP协议、分层解耦、IOC和DI)
  • 智慧社区数据可视化中枢平台——Axure全场景交互式大屏解决方案
  • ESP-IDF 开发框架:探索ESP32的强大底层世界
  • 第十届影像上海博览会落幕后,留给中国摄影收藏的三个问题
  • 佩斯科夫:若普京认为必要,将公布土耳其谈判俄方代表人选
  • 中央结算公司:减免境外央行类机构账户开户费用
  • 某博主遭勒索后自杀系自导自演,成都警方立案调查
  • 世界期待中美对话合作带来更多确定性和稳定性
  • 美国政府信用卡被设1美元限额,10美元采购花一两小时填表