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

Linux进程控制——进程等待

文章目录

    • 进程等待
      • 进程等待的必要性
      • 进程等待的方法
      • status参数
      • option参数

进程等待

进程等待的过程其实是父进程等待子进程死亡的过程

进程等待的必要性

如果子进程退出,父进程不进行处理,子进程会变成僵尸进程,有内存泄漏的风险

僵尸进程只有父进程有权处理,其他指令对其都没有效果了

父进程创建子进程是为了完成某项任务,当子进程结束后,父进程有必要了解任务完成的如何

父进程需要对子进程进行回收

进程等待的方法

waitpid系统调用的返回值是pid_t,如果等待成功则返回进程pid,失败则返回-1

这个函数有三个参数,第一个参数是pid_t pid,表示需要等待的进程id,输入-1表示等待任一子进程结束

第二个参数是int* stat_loc,这是一个输出型参数,采用指针的方法获取子进程退出状态,如果我们不关心这个状态直接传入NULL即可

第三个参数是int options,默认为0,代表阻塞等待,也有非阻塞等待的情况

还有一个wait的系统调用,只有第二个参数,就相当于waitpid的默认使用情况

#include<sys/wait.h>
#include<stdlib.h>
#include<stdio.h>int main()
{pid_t id = fork();if(id==0){int count = 5;while(count){printf("%d: 这是一个子进程,pid为:%d\n", count, getpid());count--;sleep(1);}exit(0);}waitpid(id,NULL,0);printf("等待子进程\n");return 0;
}

image.png

我们知道的是,当子进程创建出来之后,父进程是不会进入到判断语句中的,而且也没有打印等待子进程,而是一直在执行waitpid这一行,是一直等到子进程执行完毕之后才继续执行的

status参数

父进程想要了解子进程的退出码和推出信号就需要用到这个输出型参数status

而退出码和退出信号是两个数据,怎么只用一个参数来表示,这其实就用到了位图的思想,用低八位表示异常终止的信号,剩下八位表示退出的状态

画出来就是这样的

image.png

终止信号的最高位是一个core dump标志,我们暂时先不研究

因此我们就可以通过位运算来获取退出码和终止信号

退出码是(status >> 8) & 0xFF

终止信号是status & 0x7F

我们可以手动设置一下退出码来进行验证

#include<sys/wait.h>
#include<stdlib.h>
#include<stdio.h>int main()
{pid_t id = fork();int status = 0;if(id==0){int count = 5;while(count){printf("%d: 这是一个子进程,pid为:%d\n", count, getpid());count--;sleep(1);}exit(21);}waitpid(id,&status,0);printf("等待子进程\n");printf("退出码:%d; 终止信号:%d\n",(status>>8)&0xFF),status&0x7F;return 0;
}

image.png

option参数

option参数的默认值为0,表示阻塞等待,就是说父进程啥也不干,就等着子进程结束,那如果想让父进程可以在等待的时候做自己的事情,就需要用一个宏定义WNOHANG

意思是 waiting no hang 父进程会继续运行下面的代码,因为waitpid的返回值是进程退出的pid,我们也就可以用这个来判断,子进程是否结束

然后写一个循环访问即可

例如

#include<sys/wait.h>
#include<stdlib.h>
#include<stdio.h>int main()
{pid_t id = fork();if(id==0){int count = 5;while(count){printf("%d: 这是一个子进程,pid为:%d\n", count, getpid());count--;sleep(1);}exit(21);}while(1){int wait = waitpid(id,NULL,WNOHANG);if(wait==id){printf("子进程退出,id为%d\n",wait);break;}else if(wait==0){printf("子进程未退出\n");}else{perror("waitpid");exit(1);}sleep(1);}return 0;
}

image.png

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • WEB前端12-axios基础
  • SQL labs-SQL注入(四,sqlmap对于post传参方式的注入)
  • Java Web应用安全防护
  • 03--KVM虚拟化
  • Python 爬虫入门(一):从零开始学爬虫 「详细介绍」
  • ES里面常用的查询语句有哪些?
  • Pytorch使用教学2-Tensor的维度
  • 探索Python的进度条神器:tqdm
  • 51单片机嵌入式开发:20、STC89C52R基于C51嵌入式点阵广告屏的设计
  • springcloud rocketmq 新增的消费者组从哪里开始消费
  • 【开发学习笔记】什么是Springboot?
  • 【AI大模型】Prompt 提示词工程使用详解
  • SSM学习9:SpringBoot简介、创建项目、配置文件、多环节配置
  • docker 构建 mongodb
  • 阿里服务器购买与java环境搭建 实践
  • [iOS]Core Data浅析一 -- 启用Core Data
  • Apache的80端口被占用以及访问时报错403
  • canvas 高仿 Apple Watch 表盘
  • fetch 从初识到应用
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • in typeof instanceof ===这些运算符有什么作用
  • Java Agent 学习笔记
  • JavaScript 基本功--面试宝典
  • JavaScript 奇技淫巧
  • Javascript设计模式学习之Observer(观察者)模式
  • node.js
  • windows下mongoDB的环境配置
  • 机器学习学习笔记一
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 突破自己的技术思维
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • 做一名精致的JavaScripter 01:JavaScript简介
  • ​iOS安全加固方法及实现
  • #NOIP 2014# day.2 T2 寻找道路
  • #在 README.md 中生成项目目录结构
  • $.ajax()参数及用法
  • (2)(2.10) LTM telemetry
  • (70min)字节暑假实习二面(已挂)
  • (STM32笔记)九、RCC时钟树与时钟 第一部分
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (原)Matlab的svmtrain和svmclassify
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .NET COER+CONSUL微服务项目在CENTOS环境下的部署实践
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .NET 回调、接口回调、 委托
  • .NET 项目中发送电子邮件异步处理和错误机制的解决方案