【Linux系统编程】僵尸进程与孤儿进程

文章目录

  • 1. 僵尸进程
  • 2. 僵尸进程的危害
  • 3. 孤儿进程

1. 僵尸进程

上一篇文章进程的状态中最后我们提出了僵尸状态:

为了方便子进程退出后父进程或操作系统获取该进程的退出结果,Linux进程退出时,进程一般不会立即死亡,而是要维持一个Z状态即——僵尸状态。

那处在僵尸状态的进程即僵尸进程,那首先我们就要来重点理解一下僵尸进程

那我们来给大家讲一个故事:

假如你呢是一名非常自律上进的大学生,每天早晨都有到外面跑步的好习惯。
今天早上呢你正在跑步的时候,忽然后面来了一个程序员,也在跑步,但他跑的非常快,边跑边掉头发,很快就超过你跑到前面去了,你依然在后面慢慢的跑着。
突然,这个程序员跑到在你前面100M左右的地方,口吐白沫,一阵抽搐,就倒下了。
后面不远处的你看到了这个情况,非常慌张,赶紧打了120并报了警。
然后警察很快就到了,到了之后发现这个人已经不行了。
然后请问大家警察会怎么做?
会不会直接把这个人弄走,通知它的家属,然后销毁现场。
那正常情况呢应该是不会这样的。
警察应该会封锁现场,然后刚好120的人过来了,警察说,你帮我们确认了,这个人是不是已经不行了,120的医务人员说确实不行了。
然后呢警察可能会通知法医来确认这个人的死因,是自己死亡,还是被谋杀了啥的,然后进行一些相关的调查啥的。
假设最后发现这个人是自己发病死亡了,那然后警察就通知家属,让它们把人带走,然后就可以撤离现场了。

那上述的故事中:

警察发现这个人死亡后应不应该立即把这个人弄走,然后销毁现场。
不应该,而是要维护好现场,便于调查它的死因啥的…
那其实这就对应了我们上面提到的一个进程退出后不会立即死亡,而是维持一个僵尸状态,便于父进程或者操作系统获取该进程的退出结果。

那么简单总结一下:

僵尸状态(Zombies)是一种比较特殊的状态。当进程退出并且其父进程没有读取到该进程退出的返回代码时就会产生僵死(尸)进程。
僵尸进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
所以,只要子进程退出,但父进程还在运行,且父进程没有读取子进程退出的返回代码,子进程就会进入僵尸状态。

那我们写个代码给大家演示一下:

在这里插入图片描述
代码就不解释了,都是之前讲过的内容
我们运行一下
在这里插入图片描述
那我们用ps命令查看一下进程
在这里插入图片描述
我们看到现在父子进程两个的状态都是S。
那按我们上面讲的,子进程退出,父进程还在运行,且没有回收子进程获取返回码(我们现在也不会),那么子进程就会进入僵尸状态
🆗,那我们现在干掉子进程
在这里插入图片描述
然后我们再来查看
在这里插入图片描述
子进程就变成了僵尸进程

2. 僵尸进程的危害

进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态?
是的!
维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护?
是的!
那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存泄漏?
是的!因为数据结构对象本身就要占用内存,如果一直不释放那就内存泄漏了。
如何避免?后面讲

等这个进程真正被回收了,它的状态才会变成X死亡状态,此时该进程的所有资源才会被释放。

至此,值得关注的进程状态全部讲解完成,下面来认识另一种进程:

3. 孤儿进程

首先,我们给出孤儿进程的概念:

孤儿进程指的是在其父进程执行完成退出或被终止后仍继续运行的一类进程。

即如果父进程先退出,子进程继续还在运行,那么该子进程就被称为孤儿进程。

那下面我们还是写写代码来帮助大家理解:

这里我们写这样一个程序
在这里插入图片描述
子进程循环打印运行,父进程打印10次退出
写个Makefile
在这里插入图片描述
然后这里给大家解释一下这两个之前没见过的符号:
$@就代表:左边的目标文件;
$^代表:右边的所有的依赖文件

所以后续如果我们开发的时候,这个依赖文件列表里面有多个文件,我们不用一个个都列在后面,直接用这个符合就行了。

那下面我们就运行这个程序并观察一下对应的现象:

那这里呢我们要用到一条shell语句
while :; do ps axj | head -1&&ps axj | grep mytest|grep -v grep; sleep 1;echo "--------"; done
大家看不懂没关系,它的作用其实就是每个1秒去显示一下对应搜索的进程信息,并打印了一个“----------”的分割线
在这里插入图片描述
那现在我们把程序跑起来
在这里插入图片描述
那我们发现呢?
运行一段时间之后,父进程就结束退出了,后面就只剩子进程在运行了。

但是呢?这里有些问题值得我们去思考和探索:

首先第一个问题:父进程也是一个进程啊,那按照我们前面学的内容,一个进程退出时,并不会立即变为X死亡状态,而是要维持一个僵尸状态,但是这里这个父进程退出之后为啥我们没有看到Z状态呢?它直接就没了?

🆗,那大家想一下僵尸状态存在的意义是啥?
其实我们前面已经说了,是为了方便子进程退出后父进程或操作系统获取该进程的退出结果。
所以如果子进程一直没有被回收的话,那么它就会一直处在僵尸进程,那它就会一直占据资源,进而导致内存泄漏,这都是我们前面讲过的。
那这里为什么没有看到父进程处于僵尸状态,是不是因为它退出后就被回收了呢?
🆗,是的!
大家说这里的这个父进程它的父进程是谁啊?
是不是bash啊,这也是我们前面讲过的内容——命令行启动的所有程序,最后变成进程其对应的父进程都是bash。
所以,我们这里之所以没有看到父进程处于僵尸状态,就是它的父进程bash把它直接回收了

然后第二个问题我们发现

在这里插入图片描述
原来这个子进程的父进程的PID是2618,但是它的父进程退出后,它的父进程的PID变成了1,它被一个新的爹领养了
那这里我们得出一个结论:
如果一个进程的父进程退出了,而这个进程自己还在运行,那么它将会被1号进程(init进程)自动领养,那么这个被领养的进程即孤儿进程。

那大家想一下为什么?为什么操作系统要领养孤儿进程?

或者大家思考一下如果不领养孤儿进程,会发生什么?
那其实这个问题可以说我们前面已经讲过了。
如果孤儿进程不被领养,那它就没有父进程了嘛,那这样的话未来这个孤儿进程退出的时候谁来回收它,给它收尸呢?
那退出后没有人回收它,它就会一直处于僵尸状态,等待回收而没有人回收,那么就导致内存泄漏。

那再来总结一下:

在操作系统领域中,孤儿进程指的是在其父进程执行完成或被终止后仍继续运行的一类进程。这些孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

除此之外,还有一个细节也提一下:

在这里插入图片描述
我们还可以发现,它的父进程退出后,它的状态由S+变成了S,+没了。
那进程状态里面的这个+其实我们前面也提过:
带+的是前台进程,不带的是后台进程。
那他变成后台进程后呢我们CTRL+c就终止不掉它了
在这里插入图片描述
这个我们前面也演示过,而且它在后台运行我们还可以正常执行命令
在这里插入图片描述
但是这样很影响我们的使用。
所以我们可以使用kill命令把它杀掉
在这里插入图片描述
这也是之前讲过的
那这里我们再补充一个方法
killall +进程名称
在这里插入图片描述
就可以杀掉指定名称的进程。

那以上就是关于僵尸进程和孤儿进程的相关内容…
在这里插入图片描述

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

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

相关文章

C 语言关键字_at_的使用

查看一些老旧代码的时候看到有这么一段。 这个函数是轮询执行的,但是sourceinsight却没有找到vs_ucLedSegDutyRam的定义,全局搜索才找得到,结果发现原来它的定义很奇特。 里面用了_at_这个东西 _at_是让定义的vs_ucLedSegDutyRam首地址定义在…

$nextTick解决echarts宽度固定为100%的问题

问题描述:vue+element项目中使用到了tab切换选项卡,其中有一个tab下的内容是echarts,出现了echarts宽度缩减为100px无法继承100%属性。 问题: echarts渲染时tab选项卡display为none,所以width:100%没有可继承项,被echarts自带方法切割成100px。 我他喵的解决这个问题还是…

54、数组--模拟

LCR 146. 螺旋遍历二维数组 给定一个二维数组 array,请返回「螺旋遍历」该数组的结果。 螺旋遍历:从左上角开始,按照 向右、向下、向左、向上 的顺序 依次 提取元素,然后再进入内部一层重复相同的步骤,直到提取完所有…

进程的状态与转换以及组织方式

1.进程的状态 三种基本状态:运行态,就绪态,阻塞态。 1.运行状态 如果一个进程此时在CPU上运行,那么这个进程处于“运行态”。 CPU会执行该进程对应的程序(执行指令序列) 2.就绪状态 当进程创建完成后,…

[React] 性能优化相关 (一)

文章目录 1.React.memo2.useMemo3.useCallback4.useTransition5.useDeferredValue 1.React.memo 当父组件被重新渲染的时候,也会触发子组件的重新渲染,这样就多出了无意义的性能开销。如果子组件的状态没有发生变化,则子组件是不需要被重新渲…

雷达编程实战之功耗优化技术(低功耗)

本篇文章以xWRL6432为例,首先介绍了芯片内部的电源管理框架,在产品业务处理流程的不同阶段,我们可以对不同电源域进行相应的开/关来降低功耗。然后介绍了不同的硬件电源参考设计对芯片功耗的影响,又着重介绍了线性调频脉冲相关参数…

SpringBoot——常用注解

Spring Web MVC与Spring Bean注解 Controller/RestController Controller是Component注解的一个延伸,Spring 会自动扫描并配置被该注解标注的类。此注解用于标注Spring MVC的控制器。 Controller RequestMapping("/api/v1") public class UserApiContr…

cesium 雷达扫描 (线行扩散效果)

cesium 雷达扫描 (线行扩散效果) 1、实现方法 使用ellipse方法加载圆型,修改ellipse中material方法来实现效果 2、示例代码 2.1、 <!DOCTYPE html> <html lang="en"><head><<

python代码混淆与代码打包

0x00 背景 自己写的项目&#xff0c;又想保护源码&#xff0c;自己做个混淆是最方便的了。 0x01 实践 这里使用开源工具 GitHub - astrand/pyobfuscate: pyobfuscate&#xff0c;虽然git上才500多star&#xff0c;但是很好用。它的使用场景是混淆单个py文件。很多事物有开始就…

如何利用niceGUI构建一个流式单轮对话界面

官方文档 参考文档 import asyncio import time import requests from fastapi import FastAPI from nicegui import app, uiclass ChatPage:temperature: ui.slider Nonetop_p: ui.slider Noneapi_key: ui.input Nonemodel_name: ui.input Noneprompt: ui.textarea None…

文心一言 VS 讯飞星火 VS chatgpt (103)-- 算法导论10.1 1题

一、用go语言&#xff0c;仿照图 10-1&#xff0c;画图表示依次执行操作 PUSH(S&#xff0c;4)、PUSH(S&#xff0c;1)、PUSH(S&#xff0c;3)、POP(S)、PUSH(S&#xff0c;8)和 POP(S)每一步的结果&#xff0c;栈 S初始为空&#xff0c;存储于数组 S[1…6]中。 文心一言&…

第5章-宏观业务分析方法-5.3-主成分分析法

5.3.1 主成分分析简介 主成分分析是以最少的信息丢失为前提,将原有变量通过线性组合的方式综合成少数几个新变量;用新变量代替原有变量参与数据建模,这样可以大大减少分析过程中的计算工作量;主成分对新变量的选取不是对原有变量的简单取舍,而是原有变量重组后的结果,因此…

【网络协议】IP

当连接多个异构的局域网形成强烈需求时&#xff0c;用户不满足于仅在一个局域网内进行通信&#xff0c;他们希望通过更高一层协议最终实现异构网络之间的连接。既然需要通过更高一层的协议将多个局域网进行互联&#xff0c;那么这个协议就必须为不同的局域网环境定义统一的寻址…

jmh的OperationsPerInvocation参数

背景 最近再看fllink的性能基准测试时&#xff0c;发现它使用了OperationsPerInvocation注解&#xff0c;本文就来记录下这个注解的含义 官方解释 从官方文档&#xff1a;http://javadox.com/org.openjdk.jmh/jmh-core/0.9/org/openjdk/jmh/annotations/OperationsPerInvoca…

七、2023.10.1.Linux(一).7

文章目录 1、 Linux中查看进程运行状态的指令、查看内存使用情况的指令、tar解压文件的参数。2、文件权限怎么修改&#xff1f;3、说说常用的Linux命令&#xff1f;4、说说如何以root权限运行某个程序&#xff1f;5、 说说软链接和硬链接的区别&#xff1f;6、说说静态库和动态…

nginx隐藏版本号和标识

1.隐藏版本号:nginx-服务器banner泄漏风险_banner信息泄露_javachen__的博客-CSDN博客 2.隐藏nginx标识 cd /usr/local/nginx-1.24.0/src/corevi nginx.h在第14行 cd /usr/local/nginx-1.24.0/src/httpvi ngx_http_special_response.c在第22,29,36行 cd /usr/local/nginx-1.2…

【知识梳理】多级页表的原理分析【地址形成过程】【扩充思考】

多级页表的地址形成过程 首先每个进程中都至少有一个页表&#xff08;段页式可以有多个页表&#xff09;&#xff0c;都有一个页表基地址寄存器&#xff08;PTBR&#xff09;&#xff0c;以下针对三级页表进行分析。 level1&#xff1a;PTBR代表的是一级页表的基地址&#xf…

leetCode 376.摆动序列 贪心算法

如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为 摆动序列 。第一个差&#xff08;如果存在的话&#xff09;可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如&#xff0c; [1, 7, 4, 9, 2, 5] 是一个 摆动序列 &…

labview 混合信号图 多曲线分组

如果你遇到了混合信号图 多曲线分组显示的问题&#xff0c;本文能给你帮助。 在文章的最好&#xff0c;列出了参考程序下载链接。 一个混合信号图中可包含多个绘图区域。 但一个绘图区域仅能显示数字曲线或者模拟曲线之一&#xff0c;无法兼有二者。 以下显示的分两组&#…

ARM汇编基础指令整合

汇编语言的组成 伪操作 不参与程序的执行&#xff0c;但是用于告诉编译器程序该怎么编译 如&#xff1a; .text .global .end .if .else .endif .data 汇编指令 汇编器将一条汇编指令编译成一条机器码&#xff0c;在内存里一条指令…