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函数&阻塞 的相关文章

  • vmsplice() 和 TCP

    在原来的vmsplice 执行 有人建议 http lwn net Articles 181169 如果您的用户态缓冲区是管道中可容纳的最大页面数的 2 倍 则缓冲区后半部分成功的 vmsplice 将保证内核使用缓冲区的前半部分完成 但事
  • 在内核代码中查找函数的最佳方法[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我开始浏览内核代码 遇到的一件事是如何跟踪函数调用 结构定义等 有没有一种好的方法可以快速跳转到函数定义并退出 我尝试过 Source N
  • 有没有一种快速方法可以从 Jar/war 中删除文件,而无需提取 jar 并重新创建它?

    所以我需要从 jar war 文件中删除一个文件 我希望有类似 jar d myjar jar file I donot need txt 的内容 但现在我能看到从 Linux 命令行执行此操作的唯一方法 不使用 WinRAR Winzip
  • 适用于 Linux 的轻量级 IDE [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • linux-x64 二进制文件无法在 linuxmusl-x64 平台上使用错误

    我正在安装Sharp用于使用 package json 的 Nodejs 项目的 docker 映像上的映像压缩包 当我创建容器时 我收到有关 Sharp 包的以下错误 app node modules sharp lib libvips
  • 添加文件时运行 shell 命令

    我的 Linux 机器上有一个名为 images 的文件夹 该文件夹连接到一个网站 该网站的管理员可以向该网站添加图片 但是 当添加图片时 我想要一个命令来运行调整目录中所有图片的大小 简而言之 我想知道当新文件添加到特定位置时如何使服务器
  • 使用 MAX_ORDER / 包含 mmzone.h

    根据https www kernel org doc Documentation networking packet mmap txt https www kernel org doc Documentation networking pa
  • 如何让R使用所有处理器?

    我有一台运行 Windows XP 的四核笔记本电脑 但查看任务管理器 R 似乎一次只使用一个处理器 如何让 R 使用全部四个处理器并加速我的 R 程序 我有一个基本系统 我使用它在 for 循环上并行化我的程序 一旦您了解需要做什么 此方
  • 与 pthread 的进程间互斥

    我想使用一个互斥体 它将用于同步对两个不同进程共享的内存中驻留的某些变量的访问 我怎样才能做到这一点 执行该操作的代码示例将非常感激 以下示例演示了 Pthread 进程间互斥体的创建 使用和销毁 将示例推广到多个进程作为读者的练习 inc
  • 配置tomat的server.xml文件并自动生成mod_jk.conf

    我在用apache 2 2 15 and tomcat6 6 0 24 on CentOS 6 4并希望使用 tomcat 服务器的功能 通过添加以下内容自动生成 mod jk conf 文件
  • Mac OS X 上的 /proc/self/cmdline / GetCommandLine 等效项是什么?

    如何在不使用 argc argv 的情况下访问 Mac OS X 上的命令行 在 Linux 上 我会简单地阅读 proc self cmdline or use GetCommandLine在 Windows 上 但我找不到 Mac OS
  • 为什么opencv videowriter这么慢?

    你好 stackoverflow 社区 我有一个棘手的问题 我需要你的帮助来了解这里发生了什么 我的程序从视频采集卡 Blackmagic 捕获帧 到目前为止 它工作得很好 同时我用 opencv cv imshow 显示捕获的图像 它也工
  • 使用 python 脚本更改 shell 中的工作目录

    我想实现一个用户态命令 它将采用其参数之一 路径 并将目录更改为该目录 程序完成后 我希望 shell 位于该目录中 所以我想实施cd命令 但需要外部程序 可以在 python 脚本中完成还是我必须编写 bash 包装器 Example t
  • 错误:“rjags”的包或命名空间加载失败

    在终端的 conda 环境之一中 我能够成功安装包 rjags 但是 当我在该环境中运行 R 并运行库 rjags 时 出现以下错误 加载所需的包 coda 错误 rjags 的包或命名空间加载失败 rjags 的 loadNamespac
  • Linux 为一组进程保留一个处理器(动态)

    有没有办法将处理器排除在正常调度之外 也就是说 使用sched setaffinity我可以指示线程应该在哪个处理器上运行 但我正在寻找相反的情况 也就是说 我想从正常调度中排除给定的处理器 以便只有已明确调度的进程才能在那里运行 我还知道
  • 如何使用Android获取Linux内核的版本?

    如何在 Android 应用程序中获取 Linux 内核的版本 不是 100 确定 但我认为调用 uname r 需要 root 访问权限 无论如何 有一种不太肮脏的方法可以做到这一点 那就是 System getProperty os v
  • 使用os.execlp时,为什么`python`需要`python`作为argv[0]

    代码是这样的 os execlp python python child py other args this works os execlp python child py other args this doesn t work 我读过
  • 如何让 Node.js 作为后台进程运行并且永不死掉?

    我通过 putty SSH 连接到 linux 服务器 我尝试将其作为后台进程运行 如下所示 node server js 然而 2 5 小时后 终端变得不活动 进程终止 即使终端断开连接 我是否也可以使进程保持活动状态 Edit 1 事实
  • 为什么同一个curl命令在windows和linux下输出不同的东西?

    为什么同样的curl o file https www link com 命令输出不同的东西 例如 如果我运行命令curl o source txt https www youtube com playlist list PLIx6Fwnp
  • 从 Linux 内核模块中调用用户空间函数

    我正在编写一个简单的 Linux 字符设备驱动程序 以通过 I O 端口将数据输出到硬件 我有一个执行浮点运算的函数来计算硬件的正确输出 不幸的是 这意味着我需要将此函数保留在用户空间中 因为 Linux 内核不能很好地处理浮点运算 这是设

随机推荐

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

    这是前几天一刚毕业的朋友的面试题 算是面试常遇到的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函数&阻塞

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