【Linux】进程控制2-进程等待

2023-11-18

进程等待

进程等待的必要性

我们之前提到过僵尸进程,僵尸进程就是子进程先于父进程退出,子进程的退出状态信息发送给父进程但是父进程忽略处理,子进程就变成了僵尸进程,解决僵尸进程我们有三种办法, 第一就是杀死父进程,子进程就变成了孤儿进程,会被一号进程领养,一号进程会回收子进程的退出状态信息;第二种就是关机,操作系统一关,所有进程都没了;第三种就是今天的要介绍的进程等待。

父进程进行进程等待,等待子进程退出之后,回收子进程的退出状态信息,防止子进程变成僵尸进程。

wait函数

函数原型:
pid_t wait(int *status);
在这里插入图片描述

返回值:等待成功返回被等待进程的pid,等待失败返回-1.
参数:输出型参数,获取子进程的退出状态信息,如果不关心子进程的退出状态信息可以设置为NULL。
status是wait函数填充的,程序员在wait函数调用结束之后,可以通过参数获得退出进程的退出状态信息。
wait函数是一个阻塞调用函数(一定等待到被等待进程的退出状态信息才会结束函数调用)

我们来验证一下wait函数的阻塞属性:

在这里插入图片描述

上面的代码有两个进程,父进程和子进程,父子进程相互独立,抢占式执行,所以就有了两种可能性,第一就是父进程先执行,子进程后执行,此时子进程有可能变成僵尸进程,如果子进程没有变成僵尸进程,那就说明父进程的wait函数在等待中,是具有阻塞属性的;第二种是子进程先执行,父进程再执行,这种情况,wait等到到子进程的退出状态信息就很顺理成章了。

在这里插入图片描述

没有产生僵尸进程,说明两种情况下,wait都等待到了。
我们再让子进程睡眠十秒,来看一下效果:

在这里插入图片描述

运行结果:

在这里插入图片描述

子进程并没有变成僵尸进程,我们查看父进程的调用堆栈,能看到父进程正在苦苦等待子进程结束。

pstack:查看进程的调用堆栈,也就是说,用来查看进程正在运行什么代码。

我们回到wait函数的参数,是一个指向int类型的指针,我们说它是输出型参数,它指向的那个int类型的数字包含了wait向程序员传递的退出进程的退出状态信息。它一共有四个字节,不过,包含进程退出状态信息的只有后面两个字节,其中一个字节包含了退出码,两外一个字节的第一个比特位是coredump标志位,后七个比特位是退出信号位。

那如何通过进程退出状态信息判断进程是否是正常退出呢?
标准是看退出信号是否有值,如果退出信号等于0,那就是正常终止,只有正常终止才会有退出码,如果退出信号大于0,那就是异常终止,我们上次提到的那个段错误,它前面就有一个信号11,这种就是异常终止。

coredump:标志着是否产生核心转储文件,不标志进程是否异常终止。如果该比特位是1,那就是产生了核心转储文件,程序确实是异常终止。程序异常终止的时候,理论上是要产生核心转储文件的,不过此时还要关心core file size的值,如果该值是0,就有一个软限制,不允许产生核心转储文件,所以此时该比特位值是0,但是进程依然是异常终止,修改为unlimited就可以在异常终止的时候产生coredump文件,比特位就会变成1了。

我们如何通过wait的参数得到退出信号呢?

退出信号:status & 0x7f
coredump标志位:(status>>7) & 0x1
退出码:(status>>8) & 0xff

我们通过下面这段代码来举例说明一下:

在这里插入图片描述

运行结果:

在这里插入图片描述

在这里插入图片描述

运行结果:

在这里插入图片描述

waitpid函数

函数原型:

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

参数:

  • pid:
    • pid==-1,等待任意一个子进程(一个父进程可以有多个子进程),与wait等效
    • pid>0,等待进程ID与pid相等的进程。
  • status,进程退出状态信息,和wait函数的参数相同
  • options:waitpid函数可以有非阻塞属性,该属性就是通过该参数设置的。如果option参数为WNOHANG,就是设置waitpid函数为非阻塞状态,如果pid指定的子进程没有结束,则waitpid()函数返回0,不会一直等待,如果pid指定的子进程正常结束,就返回该子进程的ID。如果设置为0,那就是阻塞的,和wait函数的阻塞属性一样。
    如果是非阻塞调用函数,有一个很明显的问题就是我们不知道函数是否完成了既定的功能,所以 非阻塞调用一定要搭配循环使用

waitpid函数返回值:

  • 正常返回的时候waitpid返回收集到的子进程的进程号
  • 如果设置了选项WNOHANG,调用中waitpid发现没有已经退出的子进程可以收集,则返回0
  • 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在。

验证waitpid函数的阻塞以及waitpid函数的等待功能:

在这里插入图片描述

在这里插入图片描述

waitpid函数被设置了阻塞属性,一直等待到子进程结束之后等待到子进程的退出状态信息才结束调用,且我们查看进程状态的时候,父进程确实在等待子进程。且子进程并没有变成僵尸进程,说明子进程的退出状态信息被父进程成功回收。

验证waitpid可以有的非阻塞属性:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

子进程变成了僵尸进程,父进程陷入睡眠当中,验证了waitpid的非阻塞属性。
我们前面提到,在调用非阻塞属性的函数时,要使用循环,循环可以保证非阻塞函数完成我们想要的功能。
我们来验证一下waitpid函数的非阻塞属性,加上循环,通过循环来让它持续等待。

#include<stdio.h>                                               
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 #include<sys/wait.h>
  5 int main(){
  6   pid_t ret = fork();
  7   if(ret < 0){
  8     return 0;
  9   }else if(ret == 0){
 10     //child;
 11     printf("I am child.\n");
 12     sleep(30);
 13     printf("I am child,I exited....\n");
 14   }else{
 15     //father
 16     while(1){
 17       int w_ret = waitpid(-1,NULL,WNOHANG);
 18       //返回值:
 19       //正常情况:
 20       //    >0:返回等待到的子进程的PID
 21       //    =0:没有等待到
 22       //不正常情况下返回-1
 23       if(ret == w_ret){
 24         break;
 25       }else if(w_ret == -1){
 26         return 0;
 27       }
 28     }
 29     printf("I am father.\n");
 30     while(1){
 31       sleep(1);
 32     }
 33   }
 34   return 0;
 35 }

父进程成功回收到子进程的退出状态信息,在等待到子进程的退出状态信息之前父进程一直在执行waitpid函数,最后子进程也没有变成僵尸进程,说明waitpid函数成功完成函数功能。

当非阻塞遇到循环,不执行完功能就会一直循环,那其他功能要怎么实现呢?比如父进程的守护,这个要用到进程信号的知识,我们后面再给出答案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Linux】进程控制2-进程等待 的相关文章

  • touch命令在一个目录下创建多个文件(不同名称)

    我想制作一个在 bash 中创建目录和文件结构的脚本 我尝试过这样的事情 mkdir p 1 2 touch 1 2 a b c a b c 应该是在一个命令或其他命令中创建的文件 但由于某种原因 结构是这样的 current folder
  • numpy 未定义符号:PyFPE_jbuf

    我正在尝试使用一百万首歌曲数据集 为此我必须安装 python 表 numpy cython hdf5 numexpr 等 昨天我设法安装了我需要的所有内容 在使用 hdf5 遇到一些麻烦之后 我下载了预编译的二进制包并将它们保存在我的 b
  • 如何获取 linux 实用程序 tail 的源代码?

    这个命令确实非常有用 但是我可以在哪里获取源代码以查看内部发生的情况 thanks tail 实用程序是 Linux 上 coreutils 的一部分 源压缩包 ftp ftp gnu org gnu coreutils coreutils
  • 如何使用AWK脚本检查表的所有列数据类型? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 在这里 我正在检查表中第一列的数据类型 但我想知道AWK中表的所有列数据类型 我尝试过 但只能获得一列数据类型 例如 Column 1
  • gentoo crontab:为什么这个简单的 crontab 不起作用?

    我使用 GENTOO 发行版 crontab e 35 12 root php5 home www cron php 当我手动运行时 php5 php5 home www cron php 这有效 它向我发送了一封电子邮件 然后我检查日期
  • 在 LINUX 上使用 Python 连接到 OLAP 多维数据集

    我知道如何在 Windows 上使用 Python 连接到 MS OLAP 多维数据集 嗯 至少有一种方法 通常我使用 win32py 包并调用 COM 对象进行连接 import win32com client connection wi
  • Inotify linux 监视子目录

    是否可以以这种模式监视目录 storage data usernames Download gt storage data Download 我需要监视每个用户的下载文件夹中是否进行了更改 也许我需要创建所有路径的列表 将其放入数组中 并在
  • 如何在Python中独立于语言安装(linux)获取用户桌面路径

    我找到了 如何找到用户桌面的路径 的几个问题和答案 但在我看来它们都已失效 至少我找到的那些 原因是 如果用户安装的 Linux 不是英语 他或她的桌面很可能位于除 Desktop 例如 对于瑞典语 我相信它是在 Skrivbord 谁知道
  • 如何以编程方式从Linux中的进程名称获取进程ID

    在我的项目中 我们使用 ACE 自适应通信环境 中间件来编写可在 Windows 和 Linux 上运行的独立于操作系统的代码 要求是从进程名称中获取进程 ID 由于 ACE 不支持这一点 因此我们必须使用特定于平台的宏来分离 Window
  • C 程序从连接到系统的 USB 设备读取数据

    我正在尝试从连接到系统 USB 端口的 USB 设备 例如随身碟 获取数据 在这里 我可以打开设备文件并读取一些随机原始数据 但我想获取像 minicom teraterm 这样的数据 请让我知道我可以使用哪些方法和库来成功完成此操作以及如
  • 如何查找连接到 AF_INET 套接字的客户端的 UID?

    有什么方法或类似的东西ucred for AF UNIX如果是AF INET插座 TCP在我的例子中 找出连接到我的套接字的客户端的UID 还有 proc net tcp但它显示了UID of the creator插座的而不是连接的cli
  • 在 /dev/input/eventX 中写入事件需要哪些命令?

    我正在开发一个android需要将触摸事件发送到 dev input eventX 的应用程序 我知道C执行此类操作的代码结构如下 struct input event struct timeval time unsigned short
  • 如何使用 sed 仅删除双空行?

    我找到了这个问题和答案 https stackoverflow com questions 4651591 howto use sed to remove only triple empty lines关于如何删除三重空行 但是 我只需要对
  • SONAR - 使用 Cobertura 测量代码覆盖率

    我正在使用声纳来测量代码质量 我不知道的一件事是使用 Cobertura 测量代码覆盖率的步骤 我按照以下步骤操作http cobertura sourceforge net anttaskreference html http cober
  • 在 Linux 上的 Python 中使用受密码保护的 Excel 工作表

    问题很简单 我每周都会收到一堆受密码保护的 Excel 文件 我必须解析它们并使用 Python 将某些部分写入新文件 我得到了文件的密码 当在 Windows 上完成此操作时 处理起来很简单 我只需导入 win32com 并使用 clie
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • Godaddy 托管上的 CakePHP 控制台

    我一直在努力让我的 CakePHP 网站在 Godaddy 网格托管 帐户上运行 我的蛋糕应用程序设置是从帐户的子目录托管的 并且可以通过子域访问 我必须调整我的 htaccess 文件才能使其正常工作 现在我需要让 CakePHP 控制台
  • xsel -o 对于 OS X 等效项

    是否有一个等效的解决方案可以在 OS X 中抓取选定的文本 就像适用于 Linux 的 xsel o 一样 只需要当前的选择 这样我就可以在 shell 脚本中使用文本 干杯 埃里克 你也许可以安装xsel在 MacOS 上 更新 根据 A
  • Locale.getDefault() 始终返回 en

    unix 机器上的服务器始终使用 en 作为默认区域设置 以下是区域设置输出 LANG en US LC CTYPE C LC NUMERIC C LC TIME C LC COLLATE C LC MONETARY C LC MESSAG
  • 拆分字符串以仅获取前 5 个字符

    我想去那个地点 var log src ap kernelmodule 10 001 100 但看起来我的代码必须处理 ap kernelmodule 10 002 100 ap kernelmodule 10 003 101 等 我想使用

随机推荐

  • 基于模型的六轴机器人阻抗力控制算法(matlab simscape,机器人模型可换)

    基于模型的六轴机器人阻抗力控制算法 matlab simscape 机器人模型可换 视频中红色为期望轨迹 黑色为实际轨迹 工程可一键运行 可学到机器人阻抗力控制算法以及通过m文件设置simulink参数及调用simulink的方法 ID 4
  • FutureWarning: Criterion ‘mse‘ was deprecated in v1.0 and will be removed in version 1.2.

    出现FutureWarning Criterion mse was deprecated in v1 0 and will be removed in version 1 2 Use criterion squared error whic
  • c++如何按照空格分割字符串

    我们经常会需要在txt文本或csv中提取字符串 例如 调用了一次readline 之后 我们得到了如下一行string id 1 name 345 size 728 632 value 3 1415926 我们想把这行字符串按照空格进行分割
  • 【TypeScript】断言

    目录 概念 用法 实例 总结 概念 TypeScript类型断言是一个编译时语法 用于告诉编译器用户比编译器更加确定变量的类型 进而解除编译错误 类型断言有点类似于其他语言的类型转换 但它没有运行时的影响 只是在编译阶段起作用 所以 即使通
  • 树莓派下opencv3.4.0的安装与错误处理

    1 opencv3 4 0的下载 1 可以在树莓派的终端界面通过wegt命令下载 但下载速度可能很慢 终端输入下列代码进行下载 cd home pi Downloads wget https github com Itseez opencv
  • 【ElementUI组件】视频上传+计算视频时长

    效果如下 实现步骤 1 首先先安装官网的操作步骤安装elementui 或者 不安装直接引入 安装指令 npm i element ui S 引入方式 2 以下是参考代码 HTML代码 div div
  • 内网端口转发及穿透-

    转 内网端口转发及穿透 最近尝试了一些内网端口的转发和内网穿透 现在一起总结一下 0x01 正向和反向代理 正向代理中 proxy和client同属一个LAN 对server透明 反向代理中 proxy和server同属一个LAN 对cli
  • 执行npm install 时报错 Host key verification failed

    问题 安装依赖的时候出现Host key verification failed问题 整理了一下解决流程 1 要在git设置一下身份的名字和邮箱 git config global user name yourname gt 用户名 git
  • Unity中自定义协程函数

    Unity中提供了协程的方法 在处理一些需要异步的函数时非常方便 尤其是在处理网络请求响应的时候 但是协程函数有些时候需要自定义 这就需要自己实现满足条件的协程函数了 好在Unity提供了这样的类来帮助我们实现相关的功能 通过继承Custo
  • Springboot2.0中webflux到底优秀在哪里

    Spring boot webflux中所说的反应堆式编程reactor到底优秀在哪里 小编的Springboot2 0的课程已经快全部写完了 总结来看 对于有基础的同学学习难度不是很大 一周内就能上手 但是在小编看来编程如果说只会用 而不
  • 记一次wwwscan目录扫描后获取敏感目录登录后台

    1 开启wwwscan工具 2 配置信息 目标域名不要带协议头 直接www xxx com或者192 168 67 xxx 3 点击 扫描 等待扫描之后会在wwwscan的同级目录下生成结果文件 4 打开第三个文件 5 点击访问 说明 tx
  • [机器学习与scikit-learn-31]:算法-回归-线性模拟拟合拟合非线性数据-概述

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 123555129 目录 第1章 什么是
  • 进程和线程的详解和区别

    1 进程和线程概述 我们都知道计算机的核心是CPU 它承担了所有的计算任务 而操作系统是计算机的管理者 它负责任务的调度 资源的分配和管理 统领整个计算机硬件 应用程序是具有某种功能的程序 程序是运行于操作系统之上的 2 进程 我们编写的代
  • 交直流双电源无缝切换

    使用ATmega32编写交直流双电源无缝切换 输入过欠压保护 输出过流保护 主要使用了单片机自带的比较器功能 比较器的一端使用了LT431制作的2 5V基准源 include iom32v h define WDR asm WDR defi
  • 尚硅谷nodejs操作mongodb报错,MongoNotConnectedError: Client must be connected before running operations【已解决】

    1 准备好第一步的静态案例 2 启动mongodb服务 在cmd运行mongod Waiting for connections attr port 27017 ssl off 3 准备mongoose数据库模块化 4 新建AccountM
  • this.$el.querySelectorAll is not a function报错解决

    问题描述 使用el tree时 报错this el querySelectorAll is not a function 导致树无法渲染 问题解析 参考如下代码片段
  • [激光原理与应用-66]:激光器-器件 - 二极管

    第1章 二级管的基本原理 1 1 原理 现在的电子产品中 元件应用最多的是半导体材料 在集成电路中 也是应用的半导体单晶硅作为基底 通过离子注入技术而添加了硼和磷元素从而构成数以亿计的半导体晶体管 对于半导体元件来说 发挥作用的是PN结 在
  • 5G/NR 随机接入过程之Msg2

    21 6 Msg2 UE发送了preamble之后 将在RAR时间窗 RA Response window 内监听PDCCH 以接收对应RA RNTI的RAR 此时不考虑可能出现的测量gap 如果在RAR时间窗内没有接收到gNB回复的RAR
  • RPA经验分享--离线识别普通验证码

    了解RPA www i search com cn 学习RPA https support i search com cn 下载RPA https www i search com cn from csdn 前言 以下方法适用于简易的验证码
  • 【Linux】进程控制2-进程等待

    文章目录 进程等待 进程等待的必要性 wait函数 waitpid函数 进程等待 进程等待的必要性 我们之前提到过僵尸进程 僵尸进程就是子进程先于父进程退出 子进程的退出状态信息发送给父进程但是父进程忽略处理 子进程就变成了僵尸进程 解决僵