Linux:进程等待wait函数&阻塞

2023-11-01

进程等待的作用:

  • 父进程在它的执行代码中调用进程等待的方法,等待子进程退出,防止子进程变成僵尸进程;
  • 也就是说,进程等待是父进程调用某个接口进行等待,父进程等待子进程退出回收子进程的资源,防止子进程变成僵尸进程

进程等待的方法(如何让父进程进行进程等待):wait函数和waitpid函数
wait是waitpid的子功能
等待任意一个退出的子进程
返回值>0等待成功,返回的值是子进程pid
返回值<0等待失败

status是输出型参数,从函数内部拿出特定的数据(是一个整数),waitpid是系统函数,所以是从OS中拿出
子进程退出执行了return或者exit后,会将退出信息写入进程控制块
父进程通过wait函数,wait函数在OS中找到子进程PCB中的退出信息
子进程没退出,父进程就一直等

wait函数:

pid_t wait (int* status)

  • 参数是一个指针类型,但是该指针类型并不是要传递一个指针参数,而是一个输出型参数;
  • 将wait函数内部计算的某个结果通过status变量返回给调用者;
  • 之前所接触的输出型参数有:swap函数中的参数,交换两数的值函数进行传址,将swap的结果传到外部

在编码时有一个代码规范:
如果是输入型,参数定义成引用;
如果是输出或者输入输出参数,参数定义成指针;

wait函数的四个特性:

1.输出型参数,与其对应的有:

  • 输入型参数→调用者给被调用函数传参;
  • 输入输出型参数;

2.int* status是一个指针类型占四个字节,但是实际中只使用到后两个字节,将这两个字节分为三部分:

  • 退出码 + coredump标志位 + 退出信号
  • 高位字节表示退出码;
  • 低位的一个字节又被分为两个部分,
    第一个比特位表示coredump标志位
    后七个比特位表示退出信号
    在这里插入图片描述

退出码:程序正常退出时用到

  • main函数的return返回时,return后的数字就是退出码
  • exit和_exit中的参数就是退出码

coredump标志位,退出信号是程序异常退出时用到:

  • 为0表示该进程在退出时没有内存镜像文件的产生(也就是说没有coredump产生)
  • 为1则有镜像文件产生,当前程序退出异常
  • 退出信号进程异常退出时收到的几号信号

  • 进程正常退出时coredump标志位和退出信号被置为全0;
  • 退出码则是进程正常退出给的数值;
  • 异常退出coredump标志位和退出信号会有相应的数;
  • 也就是说程序正常退出只有退出码起作用,异常退出则要看标志位和退出信号

异常退出是因为收到了特定的信号,通过status右移7位得到
发信号的过程在信号部分讲解

用退出信号判断进程是否正常退出:

产生coredump文件不能判断进程是否正常退出的原因:

  • 程序在运行时崩溃(例如解引用空指针),该进程会收到崩溃信号;
  • 该信号可能会让进程产生一个coredump文件,这个文件并不是收到崩溃信号就一定会产生。
  • 是否产生coredump文件取决于:
    磁盘硬限制,空间大小不足;
    系统的软限制,进程可以产生coredump文件但是系统不让其产生

1.判断是否有退出信号

  • 正常退出时,退出信号7位全=0;异常退出,退出信号>0;
  • 所以
    int _status=wait(&status);
    status & 0xfff ffff;,等于0正常退出,>0异常退出

2.判断coredump标志位

  • (ststus >> 7) & 0x1;

3.判断退出码

  • (ststus >> 8) & 0xff;也就是按位与上八个一
  • 或者两个宏

使用wait函数阻止子进程变成僵尸进程

在这里插入图片描述

运行情况:

  • 父进程创建子进程后,子进程走else if,父进程走else语句;
  • 因为父子进程是抢占式执行,那么可能是父进程先执行wait并退出,子进程变成孤儿进程;
  • 也可能是子进程先执行先退出,父进程等待退出

  • 实际不管谁先运行,父进程都是正常结束的;
  • 因为这里牵扯到阻塞的概念,父进程一旦调用wait函数后,当子进程没有退出前,wait函数是不会返回;
  • 父进程调用wait函数,wait函数就压到父进程的栈帧上,子进程没有退出,父进程栈帧是不会销毁的,也就是说wait函数不会出栈返回

退出码&退出信号

进程异常退出就看退出信号,退出码没用
不关心子进程退出码,将status设置成NULL就行
WIFRXITED(status),若为正常终止子进程返回的状态则为真
若上面那个非0,提取子进程退出码
在这里插入图片描述

阻塞:

把进程从运行队列中拿出来放到等待队列中,在等待一个条件
这是在等待软件

阻塞概念:当调用结果返回之前,当前的执行流会被挂起,并在得到结果之后返回

  • 或者说:调用结果返回前,当前线程会被挂起,并在得到结果之后返回
  • 例如:父进程被wait函数阻塞,父进程就会被挂起,必须等到子进程结束后才能返回
  • 使用上述代码,只需给父进程处加一个死循环即可;
  • 运行后通过pstack+父进程进程号查看父进程栈帧;

在这里插入图片描述
在这里插入图片描述
父进程一直在wait,并没有返回;

对阻塞和非阻塞理解:
1.子进程一种在运行;

  • 阻塞:父进程等待子进程运行完后退出;这就是阻塞
  • 非阻塞:父进程不等子进程运行是否运行完毕就退出,这样可能会导致孤儿进程;这就是非阻塞

2.子进程已退出

  • 阻塞:父进程正常退出
  • 非阻塞:父进程正常退出

对于两种非阻塞的情况,父进程都是直接退出,但是两种情况父进程退出后,一种正常一种不正常

waitpid函数

返回值:
等待成功,返回子进程退出码
非阻塞等待,没有等到子进程则返回0,等待失败-1,成功返回子进程退出码

wait函数的实现是调用waitpid函数实现
在这里插入图片描述

  • 非阻塞模式下waitpid函数返回是没有等待子进程的;
  • waitpid函数在非阻塞模式下只调用一次并且也没等待到子进程退出,再不去调用该函数;
  • 等到子进程退出后子进程就会变成僵尸进程;

所以在非阻塞模式下需要搭配循环;

使用非阻塞,父进程可以在等待的同时做别的事情
在这里插入图片描述在这里插入图片描述

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

Linux:进程等待wait函数&阻塞 的相关文章

  • 如何在shell中输出返回码?

    我正在尝试通过调用自定义 shell 脚本sh bin sh c myscript sh gt log txt 2 gt 1 echo 该命令的输出是创建的后台进程的 PID 我想指导 bin sh保存返回码myscript sh到某个文件
  • 有谁知道在哪里定义硬件、版本和序列号。 /proc/cpuinfo 的字段?

    我想确保我的 proc cpuinfo 是准确的 目前它输出 Hardware am335xevm Revision 0000 Serial 0000000000000000 我可以在代码中的哪里更改它以给出实际值 这取决于 Linux 的
  • 将 jar 作为 Linux 服务运行 - init.d 脚本在启动应用程序时卡住

    我目前正在致力于在 Linux VM 上实现一个可运行的 jar 作为后台服务 我已经使用了找到的例子here https gist github com shirish4you 5089019作为工作的基础 并将 start 方法修改为
  • 如何通过ssh检查ubuntu服务器上是否存在php和apache

    如何通过ssh检查Ubuntu服务器上apache是 否安装了php和mysql 另外如果安装的话在哪个目录 如果安装了其他软件包 例如 lighttpd 那么它在哪里 确定程序是否已安装的另一种方法是使用which命令 它将显示您正在搜索
  • 内核模式下的线程(和进程)与用户模式下的线程(和进程)有什么区别?

    我的问题 1 书中现代操作系统 它说线程和进程可以处于内核模式或用户模式 但没有明确说明它们之间有什么区别 2 为什么内核态线程和进程的切换比用户态线程和进程的切换花费更多 3 现在 我正在学习Linux 我想知道如何在LINUX系统中分别
  • 是否可以创建一个脚本来保存和恢复权限?

    我正在使用 Linux 系统 需要对一组嵌套文件和目录进行一些权限实验 我想知道是否没有某种方法可以保存文件和目录的权限 而不保存文件本身 换句话说 我想保存权限 编辑一些文件 调整一些权限 然后将权限恢复到目录结构中 将更改的文件保留在适
  • 当 grep "\\" XXFile 我得到“尾随反斜杠”

    现在我想查找是否有包含 字符的行 我试过grep XXFile但它暗示 尾随反斜杠 但当我尝试时grep XXFile没关系 谁能解释一下为什么第一个案例无法运行 谢谢 区别在于 shell 处理反斜杠的方式 当你写的时候 在双引号中 sh
  • 如何在基于 Linux 的系统上的 C 程序中使用 mqueue?

    如何在基于 Linux 的系统上的 C 程序中使用 mqueue 消息队列 我正在寻找一些好的代码示例 可以展示如何以正确且正确的方式完成此操作 也许是一个操作指南 下面是一个服务器的简单示例 该服务器接收来自客户端的消息 直到收到告诉其停
  • 如何减去两个 gettimeofday 实例?

    我想减去两个 gettimeofday 实例 并以毫秒为单位给出答案 这个想法是 static struct timeval tv gettimeofday tv NULL static struct timeval tv2 gettime
  • 如果在等待“read -s”时中断,在子进程中运行 bash 会破坏 tty 的标准输出吗?

    正如 Bakuriu 在评论中指出的那样 这基本上与BASH 输入期间按 Ctrl C 会中断当前终端 https stackoverflow com questions 31808863 bash ctrlc during input b
  • C++ Boost ASIO 简单的周期性定时器?

    我想要一个非常简单的周期性计时器每 50 毫秒调用我的代码 我可以创建一个始终休眠 50 毫秒的线程 但这很痛苦 我可以开始研究用于制作计时器的 Linux API 但它不可移植 I d like使用升压 我只是不确定这是否可能 boost
  • 高效的内存屏障

    我有一个多线程应用程序 其中每个线程都有一个整数类型的变量 这些变量在程序执行期间递增 在代码中的某些点 线程将其计数变量与其他线程的计数变量进行比较 现在 我们知道在多核上运行的线程可能会无序执行 一个线程可能无法读取其他线程的预期计数器
  • 如何查询X11显示分辨率?

    这似乎是一个简单的问题 但我找不到答案 如何查询 通过 X11 存在哪些监视器及其分辨率 查看显示宏 http tronche com gui x xlib display display macros html and 屏幕宏 http
  • 为什么我可以在 /proc/pid/maps 输出中看到几个相同的段?

    测试在32位Linux上进行 代码如下 int foo int a int b int c a b return c int main int e 0 int d foo 1 2 printf d n d scanf d e return
  • Linux 上的基准测试程序

    对于一项任务 我们需要使用不同的优化和参数来对我们的实现进行基准测试 有没有一种可行的方法可以在Linux命令行 我知道时间 上使用不同的参数对小程序进行基准测试 从而为我提供CSV或类似内容的时间数据 输出可能类似于 Implementa
  • Python 脚本作为 Linux 服务/守护进程

    Hallo 我试图让 python 脚本作为服务 守护进程 在 ubuntu linux 上运行 网络上存在多种解决方案 例如 http pypi python org pypi python daemon http pypi python
  • 从 systemd bash 内联脚本创建 filename_$(date %Y-%m-%d)

    我正在尝试执行systemd计时器并希望将执行脚本的输出保存在每个日期的文件中 这是我的ExecStart脚本中的 service file ExecStart bin bash c echo date Y m d gt gt home u
  • 使用 plistBuddy 获取值数组

    var keychain access groups declare a val usr libexec PlistBuddy c Print var sample plist echo val echo val 0 Ouput Array
  • Awk - 计算两个文件之间的每个唯一值和匹配值

    我有两个文件 首先 我尝试获取第 4 列中每个唯一字段的计数 然后匹配第二个文件的第二列中的唯一字段值 File1 第 4 列的每个唯一值和 File2 第 2 列包含我需要在两个文件之间匹配的值 所以本质上 我试图 gt 如果 file2
  • 如何在 GNU/Linux 上设置 Subversion (SVN) 服务器 - Ubuntu [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一台运行 Ubuntu 的笔记本电脑 我想将其用作 Subversion 服务器 既让我自己在本地承诺 也让其他人远程承诺 要使其

随机推荐

  • 面试经典数据库查询题目(学生、课程、选课)

    这是前几天一刚毕业的朋友的面试题 算是面试常遇到的sql经典题目 记录一下 如图 在此我在电脑数据库上建立了对应的表结构 以供检验sql语句正误 建表语句 学生表 student info CREATE TABLE student info
  • 解决过拟合现象的六种姿势

    前面一文讲述的了过拟合现象产生的原因 现在讲述过拟合现象如何解决 1 增加训练数据 这是解决过拟合现象的根本办法 若没有过多的训练数据 我们可以自己增加一些假数据来在增加数据的数量 从而让模型的泛化能力增强 2 控制模型的复杂度 过于复杂的
  • Linux搭建FTP服务器

    FTP文件传输协议 什么是FTP FTP相关信息 FTP工作流程 FTP与HTTP区别 FTP相关软件包 FTP默认配置信息 FTP相关状态码 部署FTPserver lftp客户端的一些命令 FTP具体配置 匿名用户相关配置 本地用户相关
  • CSS的border边框属性 边框样式 内外边框 圆角合集

    CSS border 属性允许指定元素边框的样式 宽度和颜色 目录 1 四个边框 2 内外边框 3 边框样式 4 圆角边框 1 border边框属性 可以设置一到四个值 上边框 右边框 下边框 左边框 border top 10px sol
  • 【Scala入门】Scala下载及安装(Windows)以及Idea创建第一个scala项目

    目录 一 安装准备 二 Scala下载安装 三 Idea 创建Scala项目 一 安装准备 在安装之前 确保你的电脑上装有Jdk 8 Jdk 1 8 且环境变量配置正确 如果没有安装Jdk 请参照其他文章先安装Jdk 8 Jdk 1 8 1
  • JavaScript习题————————简单的关键字检测

    关键字检测说明 首先你输入一个字符串 然后确定 如果你输入的字符串里面有哪一个关键字 那么便输出那个关键字开头所在的位置 如果没有便返回 1 注 关键词不区分大小写 下面是代码
  • mac 下 vscode 通过wifi调试真机

    前言 继续上一篇如何在mac 环境下安装adb 这一篇我们将在有adb环境下进行无线模式的调试 在vscode下载插件 adb interface vscode 如上图输入 adb com 然后在右边进行安装 注意看下面的使用步骤 使用步骤
  • C++——打印乘法口诀表

    打印乘法口诀表 目标 利用嵌套循环 打印九九乘法口诀表 分析 1 列数 行数 计算结果 2 列数 lt 行数 include
  • 【JMeter】Jmeter分布式压测教程

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 一 原理 二 环境搭建 2 1 环境准备 2 2 slave机器配置 2 3 master机器配置 三 脚本及执行 3 1 参数化问题 3 2 GUI启动测试 3
  • SpringBoot整合Mybatis-Plus实现浏览数据新增、Redis进行热度排名

    在开发Web项目时 常用到的技术就是SpringBoot和Mybatis Plus 本文将介绍如何使用SpringBoot整合Mybatis Plus实现一个浏览数据新增功能 以及如何用Redis进行热度排名统计 最后用Vue进行数据渲染
  • python使用socket高效传输视频数据帧(连续发送图片)

    遇到的问题 网上找了一些代码 都是只能建立一次socket传输一张图片 然后断开重新连重新传 而建立一次socket代价不小 反复建立会非常消耗系统资源 因此尝试自己通过一次socket连续传输多张图片 代码问题记录 需要代码的可以直接文末
  • STM32系列(HAL库)——F103C8T6使用SPI方式点亮OLED

    目录 1 软件准备 2 硬件准备 3 CubeMX配置 1 芯片选择 2 配置RCC SYS 时钟树 3 配置SPI 4 配置GPIO 5 生成代码工程 4 代码移植 1 复制文件 2 在Keil5里添加文件 3 修改oled h文件 4
  • 【2023】华为OD机试真题全语言-题目0229-响应报文时间

    题目0229 响应报文时间 题目描述 IGMP 协议中 有一个字段称作最大响应时间 Max Response Time HOST收到查询报文 解析出MaxResponseTime字段后 需要在 0 MaxResponseTime s 时间内
  • 【JS】去除字符串首尾空格、所有空格

    1 去除所有空格 function trim str return str replace s g 2 去除首尾空格 去除字符串str头尾的空格 param str 字符串 return str去除头尾空格后的字符串 function tr
  • unittest和pytest的区别

    unittest是python的官方库 功能较少 pytest是第三方库 是基于unittest的扩展框架 可支持多种插件 目前有100多种 功能强大 pytest可兼容unittest写的用例 代码完全不用更改 一 用例编写方面 1 测试
  • LDR指令和LDR伪指令详解

    ARM32位指令的构成 ARM是RISC结构 数据从内存到CPU之间的移动只能通过LDR STR指令来完成 32bit 指令码 数据 所以32bit的一条指令不可能表示再带一个32bit的数据 实际只有其中的12bit来表示立即数 其中4b
  • 原生JS(JavaScript)

    JS 是JavaScript的简述 JS基于对象和事件驱动脚本语言 作用在浏览器上 JS的事件 onsubmit 主要用于表单的提交 绑定的位置在form标签里面 要有返回标记 如果提交的数据校验未通过 不允许表单提交 onload 用于页
  • chromedp 显示窗口

    chromedp现在默认是无头模式的 但是有的时候我们看浏览器执行的状态 还有部分操作是在无头模式下报错 所以需要显示窗口 opts append chromedp DefaultExecAllocatorOptions chromedp
  • [Unity 3d] 修改从asset store上下载的package的地址

    2020 9 16补充更新 在转移sims4的mod文件时又遇到这个问题 一直不成功 然后发现忘了要先把原文件转移到目标目录然后把原文件删了 mklink error cannot create a file when that file
  • Linux:进程等待wait函数&阻塞

    进程等待的作用 父进程在它的执行代码中调用进程等待的方法 等待子进程退出 防止子进程变成僵尸进程 也就是说 进程等待是父进程调用某个接口进行等待 父进程等待子进程退出回收子进程的资源 防止子进程变成僵尸进程 进程等待的方法 如何让父进程进行