【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://www.mzph.cn/pingmian/43962.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用linux的mail命令发送html格式的邮件

1、关闭本机的sendmail服务或者postfix服务 #执行下面的命令&#xff0c;各位大侠都对号入座吧 #sendmial service sendmail stop chkconfig sendmail off #postfix service postfix stop chkconfig postfix off#再狠一点就直接卸载吧.. yum remove sendmail yum remove postf…

欧拉部署nginx

1.下载nginx 下载地址&#xff1a;https://nginx.org/en/download.html 选择稳定版本 下的镜像文件进行下载 2.解压Nginx包 cd /root/nginx tar -zxvf nginx-1.26.0.tar.gz cd nginx-1.26.03.安装nginx相关依赖 yum -y install gcc zlib zlib-devel pcre-devel openssl o…

如何在 CentOS 中配置 Linux 命名空间(ip netns)

引言 Linux 命名空间是一项强大的技术&#xff0c;允许在同一系统上创建多个独立的虚拟化实例&#xff0c;每个实例可以拥有自己的网络栈、路由表、IP 地址等网络资源&#xff0c;实现资源的隔离和管理。本文将深入探讨如何在 CentOS 中配置和使用 ip netns 命名空间&#xff0…

【面试题】正向代理和反向代理的区别?

正向代理&#xff08;Forward Proxy&#xff09;和反向代理&#xff08;Reverse Proxy&#xff09;是两种常见的代理服务器类型&#xff0c;它们在网络通信中扮演着不同的角色&#xff0c;具有不同的功能和应用场景。 一、正向代理 1. 定义与位置 正向代理是位于客户端和目标…

TextView 实现最后一行缩进指定距离

实现图上类似的效果。 指定最大行数为三行&#xff0c;最后一行缩进指定的距离。 如果行数小于三行&#xff0c;则不缩进。 同时文字两端对齐 代码里的 JustifyTextView &#xff08;两端对齐的 Textview &#xff09;详见 Android Textview 多行文本两端对齐_android tex…

Go语言入门之基础语法

Go语言入门之基础语法 1.简单语法概述 行分隔符&#xff1a; 一行代表一个语句结束&#xff0c;无需写分号。将多个语句写在一行可以用分号分隔&#xff0c;但是不推荐 注释&#xff1a; // 或者/* */ 标识符&#xff1a; 用来命名变量、类型等程序实体。 支持大小写字母、数字…

k8s核心操作_Deployment的扩缩容能力_Deployment自愈和故障转移能力---分布式云原生部署架构搭建022

然后我们上面说了k8s中的deployment的多副本能力 然后,我们再来看 k8s中的deployment的扩缩容能力 可以看到,对于扩容,要使用 kubectl scale 命令 对于缩容 要使用kubectl scale 命令都是使用这个命令对吧 来试试,可以看到上面命令 首先看看 kubectl get pod 可以看到有…

第58期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

网络编程:TCP

一、tcp编程 注意 1.数据本身有顺序 2.发送和接收次数不需要对应 3. 1. C/S 模式 》服务器/客户端模型 server:socket()-->bind()--->listen()-->accept()-->recv()-->close() client:socket()-->connect()-->send()-->close(); int on 1; setso…

常用的设计模式和使用案例汇总

常用的设计模式和使用案例汇总 【一】常用的设计模式介绍【1】设计模式分类【2】软件设计七大原则(OOP原则) 【二】单例模式【1】介绍【2】饿汉式单例【3】懒汉式单例【4】静态内部类单例【5】枚举&#xff08;懒汉式&#xff09; 【三】工厂方法模式【1】简单工厂模式&#xf…

GuLi商城-商品服务-API-品牌管理-OSS获取服务端签名

新建第三方服务: 引入common 把common中oss的依赖都拿到第三方服务中来 配置文件: 加上nacos注解:<

HTML 标签简写和全称及其对应的中文说明和实例

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>HTML 标签简写及全称</title><style>…

Android 通知访问权限

问题背景 客户反馈手机扫描三方运动手表&#xff0c;下载app安装后&#xff0c;通知访问权限打不开。 点击提示“受限设置” “出于安全考虑&#xff0c;此设置目前不可用”。 问题分析 1、setting界面搜“授予通知访问权限”&#xff0c;此按钮灰色不可点击&#xff0c;点…

大小端详解

引例 我们知道整形(int)是4个字节&#xff0c;例如随便举个例子&#xff1a;0x01020304&#xff0c;它一共占了四个地址位&#xff0c;01,02,03,04分别占了一个字节&#xff08;一个字节就对应了一个地址&#xff09;。 那么就会有个问题&#xff1a;我们的01到底是存储在高地…

mysql 5.7.44 32位 zip安装

前言 因为研究别人代码&#xff0c;他使用了5.7的 32位 mysql &#xff0c;同时最新的 8.4 64位 mysql 不能用官方lib连接。所以安装这个版本使用&#xff0c;期间有些坑&#xff0c;在这里记录一下。 下载路径 mysql官方路径&#xff1a;https://downloads.mysql.com/archi…

Linux——多线程(五)

1.线程池 1.1初期框架 thread.hpp #include<iostream> #include <string> #include <unistd.h> #include <functional> #include <pthread.h>namespace ThreadModule {using func_t std::function<void()>;class Thread{public:void E…

Redis 7.x 系列【21】主从复制

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 工作原理2.1 建立连接2.2 全量复制2.3 命令传播2.4 增量复制 3. 拓扑架构3.…

Uniapp表单提交

template中&#xff1a; <template><view class""><button class"tianjia" click"tianjia">添加</button><view class"divOne" v-show"a"><text class"guanbi" click"gua…

本地 HTTP 文件服务器的简单搭建 (deno/std)

首发日期 2024-06-30, 以下为原文内容: 在本地局域网搭建一个文件服务器, 有很多种方式. 本文介绍的是窝觉得比较简单的一种. 文件直接存储在 btrfs 文件系统之中, 底层使用 LVM 管理磁盘, 方便扩容. 使用 btrfs RAID 1 进行镜像备份 (一个文件在 2 块硬盘分别存储一份), 防止…

网络通信、BIO、NIO

1. 涉及的网络基础知识 Socket&#xff1a; 操作系统提供的api&#xff0c;介于应用层和tcp/ip层之间的软件层&#xff0c;封装服务器客户端之间网络通信相关内容&#xff0c;方便调用 IO多路复用&#xff1a; &#xff08;I/O Multiplexing&#xff09;是一种IO操作模式&a…