当前位置: 首页 > news >正文

进程控制2——进程等待

在上一小节中我们介绍了进程的创建(fork)与退出(main函数的return与exit函数)
并且要有一个意识,进程退出的时候只有三种情况:
1.进程退出,结果正确
2.进程退出,结果不正确
3.运行异常,收到信号退出

文章目录

  • 1.进程等待
  • 2.wait/waitpid
    • 1). wait
    • 2). waitpid
  • 2.进程等待如何完成它的任务
    • 1). 进程等待解决僵尸进程内存泄漏
    • 2). 进程等待如何收到子进程退出信息?
    • 3). 从系统层面大致了解父进程获取子进程退出信息信息
  • 3.阻塞等待

现在我们还需要认识一个函数_exit函数
在这里插入图片描述
可以看到它在二号手册里,所以它是系统调用函数。它也能够终止进程。用法跟exit函数一样,那它与exit函数有什么区别呢?代码演示一下:
exit函数
在这里插入图片描述

在这里插入图片描述
_exit函数
在这里插入图片描述

在这里插入图片描述
我们发现exit函数会先刷新缓冲区的内容到屏幕上,然后再退出进程,但是
_exit函数是直接退出,没有刷新缓冲区内容,并且exit函数是标准库函数,_exit函数是系统调用函数,由此我们可以得到,exit函数是封装了_exit函数,内部还有诸如刷新缓冲区这样的其他的工作。
在这里插入图片描述
我们知道库函数,系统调用操作系统内核是这样的关系,exit函数刷新缓存区,_exit函数没有刷新缓存区,那么我们也可以得到一个结论,我们所认知的缓存区不在操作系统内部。这就是进程退出所用到的函数。

说明:虽然_exit的参数是int,但是仅有低8位可以被父进程所用。
所以_exit(-1)时,在终端执行$?发现返回值是255。

1.进程等待

当一个进程退出后没有被回收,那么它就会进入僵尸状态,并且它的父进程不回收它的话,这个进程会一直存在,会发生内存泄漏。那么进程等待的一个任务就是为了解决僵尸状态伴随的内存泄漏。
那么什么是进程等待呢?

它其实是使用wait/waitpid的方式来实现父进程对子进程资源回收的等待过程。

为什么要进程等待?上面已经说过

1.为了解决僵尸状态不回收造成的内存泄漏问题。
2.要知道子进程把任务完成的怎么样,因为什么终止,退出(退出码和接受信号),这一点不是必要的。

比如一些场景下父进程是不需要子进程把任务完成与否,子进程因为什么而退出、终止的。

2.wait/waitpid

1). wait

在这里插入图片描述
wait是一个系统调用函数,它有一个参数,我们稍后再说。它会回收任意一个子进程并会返回回收进程的id。
我们现在来展示一下任意这两个字的含义:
在这里插入图片描述
我们这里创建了五个子进程,所以掉用五次wait。
在这里插入图片描述
可以看到操作系统调度进程是不确定的,wait回收进程也是不确定的。

2). waitpid

在这里插入图片描述
waitpid可以看到有三个参数,第二个参数和第三个参数也先不说,那么显然它是专门回收特定进程的,当它的参数是下面红框中的那样的时候,它和wait没有区别,当waitpid第一个参数小于零的时候,它也是回收任意一个子进程。
在这里插入图片描述

在这里插入图片描述

2.进程等待如何完成它的任务

1). 进程等待解决僵尸进程内存泄漏

我们先搞出一个僵尸进程:
在这里插入图片描述

然后使用wait回收这个进程:
在这里插入图片描述

在这里插入图片描述

2). 进程等待如何收到子进程退出信息?

这就谈论到wait和waitpid中的int* status这个参数了。我们用C语言做题的时候,也会碰到这样的接口:
在这里插入图片描述
这种叫做输出型参数,目的是调用这个接口带回来某些东西,而这里的status带回来的就是退出码和子进程异常终止收到的信号。
话不多说代码展示:
这里退出码是0:
在这里插入图片描述

在这里插入图片描述
退出码为10:
在这里插入图片描述

在这里插入图片描述
我们看到我们的退出码是10,但是打印出来的是2560。
我们再用一个11号信号来终止子进程:
在这里插入图片描述

在这里插入图片描述
发现status的值又是10。
我们说了,这个变量可以接收到退出码和异常终止的信号,而这两个是两个东西,所以我们的status不是一个单纯的int变量,而是一个32个比特位的二进制数字,而我们也只用它的低十六位:
在这里插入图片描述
那我们现在,来验证一下是否真的是我说的这样呢,我们只需要对status进行位运算就可以:
在这里插入图片描述

在这里插入图片描述
确实是我们说的那样。那么说明wait/waitpid确实可以接收退出码和终止信号。
那我们可以这样写:
在这里插入图片描述
在这里插入图片描述
但是这里介绍两个宏:
在这里插入图片描述
WIFEXITED(status) 若此值为非0 表明进程正常结束。 若上宏为真,此时可WEXITSTATUS(status)获取进程退出状态。

3). 从系统层面大致了解父进程获取子进程退出信息信息

我们知道进程间具有独立性,所以我们无法通过一个简单的变量来获取子进程的退出信息(因为同一个变量,但凡有一个进程改变它的值,都会发生写时拷贝),所以需要系统调用来实现。
子进程在退出的时候会把代码数据销毁之后,将退出信息写到自己的pcb结构体中并将状态改为Z,然后等待父进程回收,而父进程使用wait/waitpid回收后,才可以释放子进程pcb。
在这里插入图片描述

3.阻塞等待

我们前面的的代码都是父进程等到子进程结束后,再开始回收子进程,那直接回收呢?
在这里插入图片描述
在这里插入图片描述
我们看到,父进程回收的时候是一直在等待子进程结束之后才进行的回收,才会执行后续的代码,这就是阻塞等待。这就涉及到waitpid的第三个参数:
当这个参数值为0时,就是阻塞等待。
当这个参数为WNOHANG(一个#define的常量)时,是非阻塞等待:
在这里插入图片描述
在这里插入图片描述

在这里我们发现它返回了一个值是0,但是应该是子进程的id才对,这里返回值有了不一样的解释:

返回值大于0:等待成功
返回值等于0:等待成功,但是子进程还没有结束
返回值小于0:等待失败(例如等待一个不存在的进程)

所以当我们使用非阻塞等待时需要以一个循环的方式多次等待,而我们也可以再这个循环里做一些父进程比较简单的任务。

相关文章:

进程控制2——进程等待

在上一小节中我们介绍了进程的创建(fork)与退出(main函数的return与exit函数) 并且要有一个意识,进程退出的时候只有三种情况: 1.进程退出,结果正确 2.进程退出,结果不正确 3.运行异…...

k8s service

文章目录 Service 基础概念Service 类型:Service 的工作流程:东西流量,南北流量NodePortLoadBalancer Service 基础概念 在 Kubernetes(K8s)中,Service 是一个抽象的概念,表示一个应用程序的逻…...

C语言 每日一题 PTA 11.6 day12

1.调和平均 N 个正数的算数平均是这些数的和除以 N,它们的调和平均是它们倒数的算数平均的倒数。 本题就请你计算给定的一系列正数的调和平均值。 输入格式: 每个输入包含 1 个测试用例。每个测试用例第 1 行给出正整数 N(≤1000);第 2 行给…...

Git使用规范指南

文章目录 Git使用规范指南前言分支命名规范分支合并流程规范提交信息规范Angular提交规范注意事项 通用Git忽略文件配置 Git使用规范指南 前言 由于最近写完代码之后,Git使用不规范被领导说了,所以最近通过阅读大量的相关博客快速学习Git使用规范&#…...

axios和Ajax

1.axios 官网:https://axios-http.com/zh/ CDN:https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js axios是一个请求库,在浏览器环境中,它封装了XHR,提供更加便捷的API发送请求 基本使用 // 发送 get 请求…...

Day06

1.继承 1.1 定义 让类与类之间产生子父类关系,有了继承性之后,子类就获取到了父类中声明的所有属性和方法。 1.2 优点 继承的出现减少了代码冗余,提高了代码的复用性。继承的出现,更有利于功能的扩展。继承的出现让类与类之间…...

@Tag和@Operation标签失效问题。SpringDoc 2.2.0(OpenApi 3)和Spring Boot 3.1.1集成

问题 Tag和Operation标签失效 但是Schema标签有效 pom依赖 <!-- 接口文档--><!--引入openapi支持--><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><vers…...

基础课18——智能客服系统架构

1.基础设施层 基础设施主要包括以下几点&#xff1a; 1. 硬件设施&#xff1a;包括服务器、存储设备、网络设备等&#xff0c;这是整个系统运行的物理基础。 2. 软件设施&#xff1a;包括操作系统、数据库管理系统、自然语言处理(NLP)工具和机器学习算法等&#xff0c;这些是…...

python执行cmd命令——控制电脑连接wifi——程序打包

import subprocess # 使用Popen创建进程&#xff0c;并与进程进行复杂的交互 proc subprocess.Popen(netsh wlan show network, # cmd特定的查询空间的命令stdinNone, # 标准输入 键盘stdoutsubprocess.PIPE, # -1 标准输出&#xff08;演示器、终端) 保存到管道中以便进行操作…...

Vue中nextTick的使用及原理

在Vue.js中&#xff0c;nextTick方法可以让我们在DOM更新后执行一些操作。通常情况下&#xff0c;在数据发生变化后&#xff0c;Vue.js会异步地更新DOM&#xff0c;这样可以减少不必要的DOM操作&#xff0c;提高性能。但是&#xff0c;有时候我们需要在DOM更新后对页面进行一些…...

【Linux】拓展:运维面试题,进程管理常见的7大问题

目录 一、如何判断一个程序是单线程还是多线程 二、僵尸进程是什么&#xff0c;有什么危害&#xff0c;如何解决 三、如何找回删掉的文件 四、删除文件以后&#xff0c;空间不释放 五、遇到一个病毒&#xff08;如死循环病毒&#xff09;&#xff0c;解决思路 六、机器开机…...

Android修行手册 - 一文全了解Kotlin几种静态变量、函数实现的那些事

点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&…...

Qt QTableView排序

1.简介 在开发过程中&#xff0c;我们需要通过点击表头来对QTableView或QTreeView等一系列高级视图进行排序操作&#xff0c;以下是进行排序的步骤。 步骤&#xff1a; 首先创建了一个QStandardItemModel对象或者继承QAbstractTableModel类作为数据模型&#xff0c;并设置了…...

Linux shell编程学习笔记22: () $() (()) 的用法小结

最近学习Linux Shell编程&#xff0c;对 () (()) [] [[]]等符号的用法还是有点分不太清楚&#xff0c;于是决定再梳理一下。今天先整理 () $() (()) 的用法。 1 单小括号() 1.1 子shell&#xff08;命令组&#xff09; 括号中的命令将会新开一个子shell顺序执行&#xff0c;所…...

1. Pthreads专栏简介

在基于共享内存的多处理器架构中&#xff0c;可使用线程实现并行。以前硬件供应商一般都会提供相应硬件专用的线程库&#xff0c;使得代码的可移植性成为另开发者头疼的一个问题。在UNIX系统中&#xff0c;IEEE POSIX 1003.1c标准已经定义了基于C的标准化线程编程接口规范&…...

C++17 fallthrough属性

在C17中&#xff0c;引入了[[fallthrough]]属性。这个属性主要用于switch语句中&#xff0c;用于告诉编译器&#xff0c;从上一个case标签到下一个case标签的执行是有意为之的&#xff0c;不应该被诊断为错误。 在switch-case语句中&#xff0c;如果当前case分支中不加break&a…...

STM32 蜂鸣器介绍 配置 播放音节

蜂鸣器一般被分为两类&#xff1a;有源蜂鸣器和无源蜂鸣器。其中源是振荡源。有源蜂鸣器内部有正当电路&#xff0c;可以把直流电源转换为一定频率的脉冲信号。因为它一直输出一定的频率&#xff0c;我们无法改变频率&#xff0c;我们只能通过电源&#xff0c;控制它发不发声&a…...

多目标最优化的资产配置

摘要及声明 1&#xff1a;本文主要对基于均值方差最优化的资产配置方法进行拓展&#xff0c;从多目标最优化的角度看待资产配置并可视化展示&#xff1b; 2&#xff1a;本文主要为理念的讲解&#xff0c;模型也是笔者自建&#xff0c;文中假设与观点是基于笔者对模型及数据的…...

word图片的标题跑到了图片的上方。

问题描述&#xff1a;在写论文时&#xff0c;在word文档中插入了一个svg图片&#xff0c;然后在图片下方输入标题。后面可能是调整了svg图片的大小&#xff0c;标题跑到了图片的上方。 具体情况如下图所示。标题明显跑到了图片的上方。 解决办法&#xff1a;把svg图片格式调成…...

electron打包下载资源失败,设置国内镜像

0.electron介绍 Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows、Linux及macOS上运行的跨平台应用。可以用原生html写&#xff0c;也可以用vue等…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准

城市路内停车管理常因行道树遮挡、高位设备盲区等问题&#xff0c;导致车牌识别率低、逃费率高&#xff0c;传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法&#xff0c;正成为破局关键。该设备安装于车位侧方0.5-0.7米高度&#xff0c;直接规避树枝遮…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...

Qt的学习(一)

1.什么是Qt Qt特指用来进行桌面应用开发&#xff08;电脑上写的程序&#xff09;涉及到的一套技术Qt无法开发网页前端&#xff0c;也不能开发移动应用。 客户端开发的重要任务&#xff1a;编写和用户交互的界面。一般来说和用户交互的界面&#xff0c;有两种典型风格&…...

Yii2项目自动向GitLab上报Bug

Yii2 项目自动上报Bug 原理 yii2在程序报错时, 会执行指定action, 通过重写ErrorAction, 实现Bug自动提交至GitLab的issue 步骤 配置SiteController中的actions方法 public function actions(){return [error > [class > app\helpers\web\ErrorAction,],];}重写Error…...