父子进程之间的等待(wait和waitpid的介绍+原理),status的介绍+恢复退出码(位运算+宏),非阻塞等待(宏),signal查看

目录

父子进程之间的等待

介绍

为什么要有等待

内存泄漏

如何等待

介绍

pid_t wait (int* status)

介绍

status指针

示例

​编辑

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

pid

 options

WNOHANG -- 非阻塞等待

示例

status

查看status

status问题

正常退出时,恢复退出码

位运算

进程崩溃,查看signal

引入

kill指令

示例 -- 野指针

示例 -- kill -9

为什么一定要通过上面的这些函数拿到退出信息

那么,这些问题wait / waitpid 是如何解决的呢?


父子进程之间的等待

介绍

通常用于实现协作和同步,以确保父进程等待子进程完成 / 等待子进程的某个事件

为什么要有等待

  • 在某些情况下,父子进程需要在执行过程中相互协同工作,以确保程序的正确性和完整性
  • 等待可以用于协调它们的活动,使它们按照某种特定的顺序执行任务
  • 父进程可能需要等待这些子进程完成执行,以便获取子进程的结果、收集信息或继续执行其他操作
  • 只有当父进程获取到子进程的退出状态信息时, 才会回收子进程资源(所以,如果父进程提前退出,将会造成子进程的资源泄漏)

内存泄漏

  • 这里的内存泄漏是指进程的task_struct还保留在内存中(也就是系统资源泄漏)
  • task_struct由os维护,其他人没有权限来释放,只能等待父进程回收 / 父进程退出后由init进程回收
  • 而我们平常说的内存泄漏是指进程在堆上开辟的空间没有被释放
  • 但其实一旦进程退出,这些由语言申请的空间都会被释放掉

如何等待

介绍

 头文件:

pid_t wait (int* status)

介绍
  • 用于父进程等待子进程的终止,并获取其退出状态
  • 如果当前没有子进程终止,父进程将被阻塞,等待一个子进程终止(也就是阻塞式等待)
  • 当一个子进程终止后,父进程会解除阻塞,并获取已终止子进程的pid(返回值),如果没有子进程终止,返回-1
status指针
  • 用于存储子进程的退出状态信息
  • 当该位置有参数时,由os提供该值
  • 如果不关心子进程的退出状态,可以传递NULL
示例

下面的代码流程是:

  • 创建一个子进程,子进程打印信息后睡眠5s,
  • 而父进程打印信息后睡眠7s,再等待进程状态变化
  • (其中的2s内可以看到子进程处于僵尸状态)
  • 后调用wait函数,用以回收已终止子进程的资源

可以看到,我们成功等待到了子进程:

 

子进程24295从僵尸状态Z+ -> 进程退出了,说明父进程等待子进程成功后,就释放掉了子进程的资源

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

pid
  • 如果为-1,则代表等待任意一个子进程终止(与wait()等价)
  • >0,它在等待指定的子进程
 options

默认是0,进行阻塞式等待

  • 此时父进程不做任何事,在等待队列中等待子进程的状态改变
  • 不占用cpu的时间片,这期间调度器调用其他可用进程
  • 阻塞的上层表现 -- 该进程无反应(因为cpu没有调度它)
WNOHANG -- 非阻塞等待
  • 宏定义(系统提供的大写标识位:一般都是宏定义,将没有特殊意义的数字定义成宏,使用时更加清晰)
  • 如果指定的子进程状态未改变,立即返回0 
  • 此时,父进程就可以执行waitpid后面的代码了(可以在等待的过程中完成一些小的工作模块)
  • 父进程在继续执行其他任务的同时,周期性地调用waitpid函数,以不断检查子进程的状态,从而及时获取子进程的退出状态
示例

可以看到,在父进程在等待子进程的过程中,依然在工作中

最终成功等待到子进程

 

status

和wait中的status用法一样

如果为waitpid(-1,NULL,0),则与wait(NULL)等价,看到的结果相同

查看status

如果我们尝试查看status呢?就可以使用waitpid(ret,&status,0):

我们让子进程睡眠5s后,带着退出码=2023退出,然后由父进程等待子进程退出,拿到退出码

 但是,结果似乎并不是我们想象中的那样(虽然子进程成功退出了,但是status的值很奇怪捏):

拿到的退出码怎么会是59136呢?

status问题

为什么上面的代码会出现值不一样的情况呢?

实际上status在函数内部并不是当做一个整数来对待,而是拆成32位bit位

其中低16位是我们需要了解的

正常退出时,恢复退出码
  • 如果程序执行完毕 (可以通过 宏(WIFEXITED) / 退出码 来判断是否正常退出)
  • 它会将实际的退出码放入[status的低16位]的后8位,然后将该数作为status的值
  • 所以我们得到的status会比设置的退出码(2023)大很多
位运算
  • 可以通过位运算的方式,将原本的退出码还原 (status>>8) & 0x0000 00ff
  • 右移8位是为了将退出状态移到该数的低8位,然后按位与拿到低8位
  • 也可以通过拿到该值 (WEIXTSTATUS)
进程崩溃,查看signal
引入
  • 如果进程崩溃提前终止了呢?这时的退出状态就没有意义了(会是0)
  • 其实想一想,运行的程序崩溃 本质上就是 os将这个进程杀死了
  • 那它是如何在茫茫进程中,单单选中了崩溃的进程把它杀死了呢?
  • 是通过程序发送信号通知os的
kill指令
  • 实际上,我们的kill指令就是通过os向进程发送信号,来对进程进行操作
  • 其中,信号是有编号的,1-31是普通信号,我们要学的也就是这31个信号
  • 然后,通过将 信号 放入 status的低7位 (第8位是core dump标志,在gdb调试崩溃程序中用到)
  • 我们可以通过按位与拿到低7位(& 0x0000 007f)
示例 -- 野指针
示例 -- kill -9

除了出现错误使程序崩溃,也可以是外力直接杀掉

  • 当子进程在死循环时,可以使用kill指令杀掉它(通过发送信号)

为什么一定要通过上面的这些函数拿到退出信息

  • 如果设置为全局变量呢?似乎可以拿到
  • 但其实,因为你要根据不同的判断条件来修改退出码,所以此时必定发生写时拷贝
  • 那么就会导致父子进程中的那个全局变量实际上有两个,父进程无法拿到子进程的变量,进程之间具有独立性

  • 除此之外,信号你又该如何拿到呢?

那么,这些问题wait / waitpid 是如何解决的呢?

  • 首先,那些退出信息也是数据,它就被存放在描述进程的pcb中
  • 还记得僵尸进程吗?
  • 为什么它有害,就是因为它的task_struct还保留在内存中,占用着资源
  • 必须要由父进程拿到子进程的退出码,才能释放它
  • 但是,进程之前不是有独立性吗?父进程是如何拿到子进程中的退出码的?
  • 实际上是由os完成的
  • os会自动回收子进程的资源,并将退出状态信息传递给父进程
  • 那么,wait和waitpid也是一样的道理,也是os完成实际的工作

  • wait和waitpid是系统调用,它是由os提供的接口
  • 因此由os维护的task_struct自然可以被自己的接口调用啦!!!
  • 所以,父进程是无法拿到子进程内部的信息的,但是os帮它拿到了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/115656.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mybatis与Mybatis-Plus(注解与Xml)(单表与多表)

准备工作 这里我们准备了两个与数据库表对应的实体类,stu为学生表,cls为班级表 类属性上的注解如 TableId等 为Mybatis-Plus的注解,使用mybatis会无视掉这些注解 在Stu 类的最后一个属性我们定义了Cls实体类的对象,对于单表查询&…

EASYX输出文字

在EASYX中绘制出字符串和字符 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <easyx.h> #include <iostream> #include <math.h> #include <stdlib.h> #include <conio.h> #include <time.h> #define PI 3.14、 //…

Windows 下编译 TensorFlow 2.9.1 CC库

参考 Intel 的 tensorflow 编译指导&#xff0c;不过项目还是可以用 TF原本的&#xff0c;不是一定要选择Intel 的TF版本。 安装 MSVC 2019 安装 Intel OneDNN OneMKL 似乎也可以不安装 ( & ) https://www.intel.cn/content/www/cn/zh/developer/articles/tool/one…

算法随想录算法训练营第四十七天| 647. 回文子串 516.最长回文子序列

647. 回文子串 题目&#xff1a;给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。回文字符串 是正着读和倒过来读一样的字符串。子字符串 是字符串中的由连续字符组成的一个序列。具有不同开始位置或结束位置的子串&#xff0c;即使是由相同的字…

开发知识点-PHP从小白到拍簧片

从小白到拍簧片 位异或运算&#xff08;^ &#xff09;引用符号(&)strlen() 函数base64_encode预定义 $_POST 变量session_start($array);操作符php 命令set_time_limit(7200)isset()PHP 命名空间(namespace)new 实例化类extends 继承 一个类使用另一个类方法error_reporti…

【C语法学习】16 - fclose()函数

文章目录 1 函数原型2 参数3 返回值4 示例 1 函数原型 fclose()&#xff1a;关闭已打开的文件&#xff0c;并刷新缓冲区&#xff0c;函数原型如下&#xff1a; int fclose(FILE *stream);2 参数 fclose()函数只有一个参数stream&#xff1a; 参数stream是一个指向FILE类型结…

Daily neaty和希亦内衣洗衣机哪款好,高性价比内衣洗衣机测评

现在市面最火的小家电莫过于是内衣洗衣机&#xff0c;那么它是否真的好用还是只是智商税呢&#xff1f;但关于内衣洗衣机&#xff0c;很多小伙伴都会选入手来释放自己的双手的&#xff0c;现在内衣洗衣机品牌众多&#xff0c;而且Daily neaty和希亦CEYEE-ACE这两个大品牌会被许…

【漏洞复现】Apache_HTTPD_换行解析漏洞(CVE-2017-15715)

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描3、漏洞验证 1.5、深度利用GetShell 1.6、修复建议 说明内容漏洞编号CVE-2017-15715漏洞名称Ap…

京东数据平台:2023年9月京东智能家居行业数据分析

鲸参谋监测的京东平台9月份智能家居市场销售数据已出炉&#xff01; 9月份&#xff0c;智能家居市场销售额有小幅上涨。根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;今年9月&#xff0c;京东平台智能家居的销量为37万&#xff0c;销售额将近8300万&#xff0c;同比增…

如何理解所谓的【指令执行速度】

公式&#xff1a; 指令执行速度 主频/平均CPI 先不看主频&#xff0c;如下图&#xff0c;假设一秒钟能有4个正弦波&#xff0c;那就说明频率是4。 而计算机很厉害&#xff0c;一秒能有很多个正弦波 把一个正弦波&#xff0c;看做一个时钟周期 则主频表示&#xff0c;计算机…

g.Grafana之Gauge的图形说明

直接上操作截图 1. 创建一个新的Dashboard 2.为Dashboard创建变量 【General】下的Name与Label的名称自定义 【Query options】 下的Group可以填写Zabbix内的所有组/.*/ , 然后通过Regex正则过滤需要的组名 3.设置Dashboard的图形 我使用文字来描述下这个图 1.我们在dash…

Java数组小练习求出数组中的最大值

加油&#xff0c;新时代打工人&#xff01; Java基础八之数组的定义和获取元素 package demo;/*** author wenhao* date 2023/11/04 10:47* description 数组练习*/ public class ArrDemo {public static void main(String[] args) {//求一个数组中的最大值int [] arr {66,12…

YOLOv7独家原创改进:新颖自研设计的BSAM注意力,基于CBAM升级

💡💡💡本文全网首发独家改进:提出新颖的注意力BSAM(BiLevel Spatial Attention Module),创新度极佳,适合科研创新,效果秒杀CBAM,Channel Attention+Spartial Attention升级为新颖的 BiLevel Attention+Spartial Attention 1)作为注意力BSAM使用; 推荐指数:…

clusterprolifer go kegg msigdbr 富集分析应该使用哪个数据集,GO?KEGG?Hallmark?

关注微信&#xff1a;生信小博士 5 Overview of enrichment analysis Chapter 5 Overview of enrichment analysis | Biomedical Knowledge Mining using GOSemSim and clusterProfiler 5.1.2 Gene Ontology (GO) Gene Ontology defines concepts/classes used to describ…

氮化镓功率放大器长期记忆效应的补偿

标题&#xff1a;Compensation of Long-Term Memory Effects on GaN HEMT-Based Power Amplifiers 来源&#xff1a;IEEE TRANSACTIONS ON MICROWAVE THEORY AND TECHNIQUES DPD&#xff1a;数字预失真&#xff08;Digital Pre-Distortion&#xff09;RF PA&#xff1a;射频功…

数据结构(超详细讲解!!)第十九节 块链串及串的应用

1.定义 由于串也是一种线性表&#xff0c;因此也可以采用链式存储。由于串的特殊性&#xff08;每个元素只有一个字符&#xff09;&#xff0c;在具体实现时&#xff0c;每个结点既可以存放一个字符&#xff0c;也可以存放多个字符。每个结点称为块&#xff0c;整个链表称为块链…

python使用requests+excel进行接口自动化测试

在当今的互联网时代中&#xff0c;接口自动化测试越来越成为软件测试的重要组成部分。Python是一种简单易学&#xff0c;高效且可扩展的语言&#xff0c;自然而然地成为了开发人员的首选开发语言。而requests和xlwt这两个常用的Python标准库&#xff0c;能够帮助我们轻松地开发…

JavaEE平台技术——预备知识(Web、Sevlet、Tomcat)

JavaEE平台技术——预备知识&#xff08;Web、Sevlet、Tomcat&#xff09; 1. Web基础知识2. Servlet3. Tomcat并发原理 1. Web基础知识 &#x1f192;&#x1f192;上个CSDN我们讲的是JavaEE的这个渊源&#xff0c;实际上讲了两个小时的历史课&#xff0c;给大家梳理了一下&a…

C++算法 —— 贪心(2)

文章目录 1、柠檬水找零2、将数组和减半的最少操作次数3、最大数4、摆动序列5、最长递增子序列6、递增的三元子序列7、最长连续递增子序列 1、柠檬水找零 860. 柠檬水找零 如果一开始顾客给了10块&#xff0c;那就直接结束。给了5块那就收下。之后每一个位置&#xff0c;都需要…

Rtthread源码分析<1>启动文件和链接脚本

启动文件和链接脚本 1&#xff09;启动文件 ​ 启动文件里面使用的是汇编语言&#xff0c;汇编语言常常可以分为两个部分语法风格和而不同的toolchain有不同的汇编语法风格&#xff0c;通常分配unified 和 非 unified。常见的工具包有 ARM toolchains 和 GNU toolchains 。比…