【Linux】进程(9):进程控制2(进程等待)

大家好,我是苏貝,本篇博客带大家了解Linux进程(9)进程控制2,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
在这里插入图片描述


目录

  • 一. 为什么要进程等待
  • 二. 如何进行进程等待
    • 1.wait函数—系统调用
    • 2. waitpid函数
      • (A).第一个参数:pid_t pid
      • (B).第二个参数:int* status
        • a. 第二个参数是输出型参数
        • b. 这个参数表示子进程的退出信息(包括子进程的退出码和退出信号)
        • c. WIFEXITED 和 WEXITSTATUS
      • (C).第三个参数:int options

结论:任何子进程,在退出的情况下,一般必须要被父进程进行等待。进程在退出时的状态变为Z(僵尸状态),如果父进程不管不顾,那么子进程的task_struct一直存在而且所占的空间较大,造成内存泄露的问题

一. 为什么要进程等待

  1. 父进程通过等待,解决子进程退出的僵尸问题,回收系统资源(一定要考虑的)
  2. 获取子进程的退出信息,知道子进程是因为什么原因退出的(可选的功能)

二. 如何进行进程等待

1.wait函数—系统调用

先来查看一下wait函数,从头文件就可以看出,wait函数是系统调用函数。作用:等待任意一个子进程退出
在这里插入图片描述

函数的参数暂时不用管,(我们下面说waitpid中会说到)可以直接传NULL
函数的返回值是父进程等待子进程,等待成功时,子进程的pid

修改.c文件
在这里插入图片描述

上面代码的意思是先用fork函数生成一个子进程,子进程会执行ChildRun函数,执行完成后,进程终止。此时子进程是Z状态(僵尸状态)。睡眠8秒后,父进程等待子进程退出,子进程已经退出,wait函数得到子进程的pid,解决子进程退出的僵尸问题。父进程再睡眠5秒后父进程终止

在这里插入图片描述

所以wait函数是能解决子进程退出的僵尸问题

父进程在执行wait函数时,如果子进程没有退出,那么父进程一直在进行阻塞等待。阻塞?我们之前了解的阻塞是等待某种硬件资源(如键盘资源)就绪,等待时是将进程的pcb链入键盘资源的等待序列中。那我们如何理解阻塞等待子进程?

阻塞等待:将父进程的状态设为S,再链入子进程的队列中(子进程本身就是软件)。
一旦子进程退出,操作系统调度时发现子进程退出,就将父进程唤醒

2. waitpid函数

先查看waitpid函数
在这里插入图片描述

我们看见waitpid函数有3个参数

(A).第一个参数:pid_t pid

第一个参数:等待的子进程的pid。如果pid==-1,表示等待任意一个子进程,与wait等效。pid>0表示等待其进程ID与pid相等的子进程

(B).第二个参数:int* status

a. 第二个参数是输出型参数

什么是输出型参数?我们自己在代码中定义一段内存空间,把空间的地址传进来。操作系统在等待时,在底层把对应的数据通过传的指针带到用户层,让用户看到。

直接举例:
在这里插入图片描述

我们在代码中定义变量a,将a的地址通过sacnf传到操作系统,我们键盘输入的数据经过scanf函数读到了a中,最后我们可以通过打印看到a的值

b. 这个参数表示子进程的退出信息(包括子进程的退出码和退出信号)

如果只要子进程的退出码和退出信号的话,能不能直接定义2个全局变量exit_code和exit_signal,然后将退出码和退出信号分别写在exit_code和exit_signal呢?

当然不能,因为进程具有独立性,子进程写入时,会先发生写时拷贝,所以父进程看不到子进程写入的数据,因此不能使用全局变量来接收退出码和退出信号

我们来见一下这个退出信息

修改.c文件

在这里插入图片描述

status=256,这是什么意思呢?
在这里插入图片描述

status不能简单的当作整形来看待,可以当作位图来看待。status是int类型的,有32个比特位,只研究status低16比特位。其中次8个比特位表示退出状态,即退出码。前7个比特位表示退出信号,第8个比特位暂时不用理解
在这里插入图片描述

因此status=256=2^8即0000 0001 0000 0000,所以退出码=1,退出信号=0

我们如何通过代码直接打印出退出码和退出信号呢?
退出码是次8位,那我们先status>>8,再&(按位与)0xFF(即0x1111 1111)
退出信号:status & 0x7F(即0x0111 1111)

修改.c文件
在这里插入图片描述

退出码是exit函数的参数:123
因为进程没有异常,所以退出信号=0
在这里插入图片描述

让子进程死循环,在命令行中使用kill -9信号杀掉子进程
在这里插入图片描述
在这里插入图片描述

c. WIFEXITED 和 WEXITSTATUS

上面是通过将status右移或按位与得到子进程的退出码和退出信号,那有没有什么东西能够直接告诉我们退出码和退出信号呢?

WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(若退出信号为0,则为真;反之则为假)
WEXITSTATUS(status): 若WIFEXITED非零(退出信号为0),提取子进程退出码。(查看进程的退出码)

修改.c文件
在这里插入图片描述

上面代码的意思是,如果子进程代码跑完了,即正常退出,那么查看子进程的退出码。如果子进程不正常退出,提示一下。我们之前写的status右移和按位与没删除是想看看2个框框内的结果是否一致
在这里插入图片描述

结果是一致的。

我们再来看看进程不正常退出的情况,之前的.c文件只修改ChildRun函数,让里面有野指针
在这里插入图片描述

结果也是正确的,因为有野指针,所以是段错误,退出信号为11

在这里插入图片描述

(C).第三个参数:int options

我们上面讲的,都是如果子进程没有退出,那么父进程在执行waitpid时在阻塞等待,这表示在等待期间,父进程其它事情什么都没有干。那如果我们想让父进程做一些其它的事情呢?这就需要用到waitpid函数的第三个参数:int options

当第三个参数为0时,表示父进程要阻塞等待。为WNOHANG时,表示非阻塞等待:每隔一段时间就会查看子进程是否退出,如果没有退出,那就可以做其它事情。因为每隔一段时间就要查看子进程是否退出,所以非阻塞等待要配合循环一起使用,这就叫非阻塞轮询

讨论一下waitpid函数的返回值rid

  1. rid>0:等待成功,子进程退出,父进程回收成功
  2. rid<0:等待失败,可能是第一个参数有问题,等待的子进程a不是父进程b的子进程
  3. rid==0:检测是成功的(子进程a是父进程b的子进程),但是进程还没有退出,需要下一次进行重复等待

先来试试非阻塞等待,父进程暂时不做其它事情
在这里插入图片描述

在这里插入图片描述


好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

android13 设置左右分屏修改为单屏幕,应用分屏改为单屏

1.前言 android13中,系统设置变成,左边是一级菜单,右侧是二级菜单, 这样跟我们以前android7/8/9的布局是不一样的,我们需要将它修改为一级菜单,点进去才是二级菜单这种。 效果如下 2.系统设置实现分析 它这里使用的是google新出的embedding activity, 相关的知识这里…

Golang | Leetcode Golang题解之第226题翻转二叉树

题目&#xff1a; 题解&#xff1a; func invertTree(root *TreeNode) *TreeNode {if root nil {return nil}left : invertTree(root.Left)right : invertTree(root.Right)root.Left rightroot.Right leftreturn root }

24. 122.买卖股票的最佳时机II,55. 跳跃游戏, 45.跳跃游戏II,1005.K次取反后最大化的数组和

第一天没有利润&#xff0c;至少要第二天才会有利润&#xff0c;所以利润的序列比股票序列少一天&#xff01; 从图中可以发现&#xff0c;其实我们需要收集每天的正利润就可以&#xff0c;收集正利润的区间&#xff0c;就是股票买卖的区间&#xff0c;而我们只需要关注最终利…

在FPGA程序中Handshake(握手)和Register(寄存器)区别

在FPGA程序中&#xff0c;Handshake&#xff08;握手&#xff09;和Register&#xff08;寄存器&#xff09;是两种不同的通信和数据传输机制。它们各有特点和适用场景。以下是它们的区别和应用场景的详细解释&#xff1a; Register&#xff08;寄存器&#xff09; 特点&#…

CentOS6禁止锁屏

在电源中设置后还是会锁屏, 原因是有屏幕保护程序 电源管理都 “从不” 一些AI的回答 在CentOS 6系统中&#xff0c;如果你想要禁用锁屏功能&#xff0c;可以编辑/etc/kbd/config文件。这个文件通常包含了键盘相关的设置&#xff0c;包括密码策略和屏幕锁定选项。 首先打开终…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第一篇 嵌入式Linux入门篇-第十六章 Linux 第一个程序 HelloWorld

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

14-57 剑和诗人31 - LLM/SLM 中的高级 RAG

​​​ 首先确定几个缩写的意思 SLM 小模型 LLM 大模型 检索增强生成 (RAG) 已成为一种增强语言模型能力的强大技术。通过检索和调整外部知识&#xff0c;RAG 可让模型生成更准确、更相关、更全面的文本。 RAG 架构主要有三种类型&#xff1a;简单型、模块化和高级 RAG&…

数据库第五次作业---多表查询

数据库第五次作业----多表查询 新增员工表emp和部门表dept create table dept (dept1 int ,dept_name varchar(11)) charsetutf8; create table emp (sid int ,name varchar(11),age int,worktime_start date,incoming int,dept2 int) charsetutf8; insert into dept values (…

算法:字符串相关

目录 题目一&#xff1a;最长公共前缀 题目二&#xff1a;最长回文子串 题目三&#xff1a;二进制求和 题目四&#xff1a;字符串相乘 题目一&#xff1a;最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀 如果不存在公共前缀&#xff0c;返回空字符串 "…

阶乘尾数00

题目链接 阶乘尾数 题目描述 注意点 算出 n 阶乘有多少个尾随零 解答思路 n阶乘有多少个尾随零取决于阶乘中有多少个2 * 5的组合&#xff0c;其中阶乘中2的数量一定多于5的数量&#xff0c;所以关键是要找到由多少个质因子5n的阶乘中质因子5的数量等于不断将n除以5&#x…

STM32快速搭建项目框架

注&#xff1a;编写本博客的原因&#xff0c;学习期间基于复习之前知识点的需要&#xff0c;故撰写本教程&#xff0c;即是复习前面的知识点也是作为博客的补充 1.0 文件夹的创建 创建一个STM32项目为模版工程&#xff0c;问价夹下分别包含4个子文件夹&#xff0c;一个是Librar…

【C++项目】从零实现一个在线编译器

前言 身为一名程序员&#xff0c;想必大家都有接触过像leetcode这样的刷题网站&#xff0c;不知你们在刷题的过程中是否思考过一个问题&#xff1a;它们是如何实现在线编译运行的功能。如果你对此感到好奇&#xff0c;那么本文将一步步带你来实现一个简易在线编译器。 项目概…

深入了解线程锁的使用及锁的本质

文章目录 线程锁的本质局部锁的使用 锁的封装及演示线程饥饿问题 线程加锁本质可重入和线程安全死锁问题 根据前面内容的概述, 上述我们已经知道了在linux下关于线程封装和线程互斥,锁的相关的概念, 下面就来介绍一下关于线程锁的一些其他概念. 线程锁的本质 当这个锁是全局的…

Vue使用Echarts(入门级)

最终效果&#xff1a; npm install echarts --save // 先安装echarts<template><!-- 创建一个dom区域用于挂载echarts图表 --><div id"chart" style"width: 600px;height:500px;"/> </template> <script> import * as ech…

WPF依赖附加属性

依赖附加属性的定义 基本过程&#xff1a;声明、注册、包装 依赖附加属性必须在依赖对象&#xff0c;附加属性不一定&#xff0c;关注的是被附加的对象是否是依赖对象 快捷方式&#xff1a;propa tab 关键字&#xff1a;RegisterAttached // 方法封装 public static int …

4.MkDocs样式

学习 Admonitions(警告) - Material for MkDocs (wdk-docs.github.io) 提示 - Material for MkDocs 中文文档 (llango.com) Buttons(按钮) - Material for MkDocs (wdk-docs.github.io) 建议去看这些网站&#xff0c;更为详细。 常用功能 便利贴 ​​ 开启 markdown_ex…

FL Studio 24.1.1.4234 (Windows) / 24.1.1.3884 (Mac OS X)

FL Studio 24.1.1.4234 (Windows) / 24.1.1.3884 (Mac OS X) 主页多媒体音频编辑FL Studio 24.1.1.4234 (Windows) / 24.1.1.3884... FL Studio 图标 FL Studio&#xff08;前身为 FruityLoops&#xff09;是一款功能强大的音乐制作环境或数字音频工作站&#xff08;DAW&#x…

基于Java的科大讯飞大模型API调用实现

写在前面&#xff1a;因为现在自己实习的公司新拓展的一个业务是结合AI的低代码平台&#xff0c;我负责后端的开发&#xff0c;之前一直都是直接使用gpt或者文心一言等ui界面来直接使用大模型&#xff0c;从来没有自己调接口过&#xff0c;所以本文记录一下自己第一次使用大模型…

【密码学】分组密码概述

一、分组密码的定义 分组密码和流密码都是对称密码体制。 流密码&#xff1a;是将明文视为连续的比特流&#xff0c;对每个比特或字节进行实时加密&#xff0c;而不将其分割成固定的块。流密码适用于加密实时数据流&#xff0c;如网络通信。分组密码&#xff1a;是将明文数据…