进程状态(三)----- linux 中具体的进程状态(下)

目录

  • 前言
  • 1. T && t 状态
  • 2. X 与 Z 状态
  • 3. 孤儿进程

前言

继上一篇文章 进程状态(二)----- linux 中具体的进程状态(上) 介绍了 linux 系统中具体的 R、S、D 状态,而这篇文章继续介绍 linux 系统中剩下的三种状态,T && t 状态,X 与 Z 状态,以及孤儿进程的由来。

/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};

1. T && t 状态

T 和 t 状态,我们放在一块讲,因为在如今的 linux 系统中,这两个基本已经没有什么区别了。所谓 T 状态,就是 stop,就是让进程停下来。

当我们进程跑起来的时候,我们可以通过如下指令,将进程暂停一下。

[outlier@localhost process2]$ kill -l1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	其中的 19 信号就是将进程暂停,18 信号恢复进程(恢复之后的进程会变为后台进程,需要通过 kill 指令杀掉进程才能够关闭)

在这里插入图片描述

大家会不会有一个疑问就是,一个进程处于暂停状态 和 一个进程处于 sleep 状态,有什么区别吗?在最直观的理解上,这两种进程都是不被 cpu 执行的进程。所以为什么进程要暂停下来呢?它是不是也像 sleep 一样,在等待某种资源的就绪呢?

面对这类问题,我们可以这样去解读,有时候我们就是想要暂停一下这个进程,等待其它事件的发生,而非等待某种资源的就绪,我们可以将其设置为 T 状态,而 T 状态下,进程的代码就完全暂停了,一般而言也不接受其它信号了,并且 T 状态在某种程度上也算是一种阻塞状态。与 sleep 不同的是,sleep 一定是在等待某种资源,但是 stop 状态不一定是在等待资源,也可以是人为控制下的暂停。

那么为什么我们要暂停一个进程呢? ---- gdb 调试的时候,是不是就是 gdb 帮助我们暂停进程的?

在这里插入图片描述

借助 gdb,进程运行到断点处停下来了,此时的进程状态从 sleep 变为了 stop(只不过是 小 t 的暂停状态)。所以凭什么你运行到断点处,你的代码就很乖的停下来了,这一切不都是 gdb 这个调试工具帮你做的吗,而这种场景就是暂停进程的应用场景之一。、

2. X 与 Z 状态

X(dead) 状态,字面意思直接拿捏,它就是死亡状态!一个进程处于死亡状态,是什么含义?不就是这个进程因为各种原因然后停止运行了,而这个状态只是一个返回状态,也无法在任务列表里看到这个状态。

但是进程在进入 dead 状态之前,背后可是存在着一系列的事情,简单说,那就是,进程因为某种原因挂掉了,它并不会马上进入 X 状态,而是先进入 Z 状态,即僵尸状态。

那么背后是怎么一个事呢?讲个故事。

有一天早晨,张三和往日一样进行着晨跑。途中,有一个看起来较为专业的哥们,从张三的身边一闪而过,张三一开始也没多想,还是按照自己的节奏跑着。不久后,张三突然发现前面有个人 “躺平” 了,正好是刚刚一闪而过那哥们。张三哪见过如此场面,直接先后拨打了120,110。等待救护车来临之后,做了急救措施,最终宣判那哥们 dead 了,而此时帽子叔叔也已经赶到。所以既然现在人也已经彻底躺平了,于是救护人员也就离开。此刻,这个哥们已经彻底躺平是事实,但是帽子叔叔并没有宣布其躺平的消息,也没有立刻通知哥们的家属对其进行回收,而是叫了两法医对那哥们进行鉴定(判断是自杀?ta 杀?意外躺平?),毕竟好端端的一个人,突然在大庭广众之下彻底躺平,总得给社会一个交代吧?直到法医鉴定完毕,确定那哥们的躺平原因之后,帽子叔叔才正式通知其家属来认领并回收那哥们。

而在张三看到那哥们躺平开始,一直到法医鉴定躺平原因这段期间内,那哥们就一直需要在那躺平着,此时这个人的状态就称为 僵尸状态!当帽子叔叔那边鉴定完这哥们躺平的原因之后,准备通知家属进入到回收阶段了,那么这个人的状态就称为死亡状态。

所以进程也如此,一个进程退出了,并不是立刻进入 dead 状态,而是操作系统会将该进程的退出信息维持一段时间,以让关心这件事的主体得知该进程退出的原因等信息。所以对一个已经退出的进程,操作系统在维护其退出信息的这段时间内,这个进程的各种资源还没有得到释放的,我们就把这种进程称为 僵尸进程!

而一个进程退出之后,那么最关心这个进程的肯定是他的父进程。假设今天有一对父子进程,子进程退出了,但是它的父进程迟迟没有来 “关心” 它,自顾自的运行着,那么操作系统就必须把子进程的状态一直维持着,直到父进程前来回收子进程。所以再次强调,我们把这种已经死掉的进程,但是又需要有父进程前来回收的这种进程的状态,称为Z 状态,即僵尸状态。 到这里,讲了这么多,那总得见一见僵尸进程吧?

int main()
{pid_t pid = fork();if(pid == 0){// 子进程int cnt = 5;while(cnt){cout << "I am a child process, pid: " << getpid() << ", ppid: " << getppid() << ", cnt: " << cnt << endl;cnt--;sleep(1);}exit(0);}else{// 父进程while(1){cout << "I am a parent process, pid: " << getpid() << ", ppid: " << getppid() << endl;sleep(1);}}
}

在这里插入图片描述

在这次测试中,我们先退出了子进程,而在退出前,父子进程绝大部分时间都处于 sleep 状态,当子进程退出后,由于父进程并没有对子进程进行回收,因此子进程所呈现出来的状态并不是 dead 状态,而是 zombie 僵尸状态。

所以一个进程退出之后,没有及时被其父进程主动回收,这个进程资源就会一直被维持在内存当中,而这种进程既然已经变成 Z 状态了,那么它就一定不会被操作系统调度了,更不会被运行。所以这种问题就会导致 内存泄漏!而为什么在我们关闭我们的 test 进程之后,其创建出来的子进程变为 Z 状态(这现在我可以理解,因为父进程没有主动回收),那为什么其父进程却并没有呈现 Z 状态呢?而是直接退出了,难道是父进程的父进程对其进行了回收吗?

3. 孤儿进程

没错,在运行 test 这个程序之后,bash 这个进程会自动为 test 创建出进程,而 bash 作为 test 的父进程,当 test 这个进程退出时,bash 就有对它进行回收的义务!而事实就是如此,子进程是 test 这个进程创建出来的,但当子进程退出时,由于父进程并没有对其进行关心,因此该子进程的退出信息就要一直被维护下去(退出信息也是数据,保存在 task_sturct 中,也相当于在维护 PCB)。

那相反过来呢?如果是父进程退出了,子进程还在继续运行会是怎么样的现象?父进程提前退出,那子进程退出后变为 Z 状态,那是如何处理的呢?

int main()
{pid_t pid = fork();if(pid == 0){// 子进程int cnt = 500;while(cnt){cout << "I am a child process, pid: " << getpid() << ", ppid: " << getppid() << ", cnt: " << cnt << "\n";cnt--;sleep(1);}exit(0);}else{// 父进程int cnt = 5;while(cnt){cout << "I am a parent process, pid: " << getpid() << ", ppid: " << getppid() << ", cnt: " << cnt << "\n";cnt--;sleep(1);}exit(0);}
}

在这里插入图片描述

当父进程先退出了,留下子进程进行在跑的现象是,父进程退出那一刻,就立马被它的父进程(即 bash 回收了),所以也就检测不到父进程的进程信息了,但是子进程的 ppid 不再是一开始的父进程,而是变为了 1,无脑猜测,这个 pid 为 1的进程,就是我们的操作系统(也即 init 进程)!而我们把上述这种情况,父进程先退出,子进程就称之为“孤儿进程”!

所以现在也就可以回答一开始提出的问题了。父进程先退出,子进程就会被 1号 init 进程领养,所以当子进程退出,变为 Z 状态,自然就是由 1 号进程对其进行回收。而为什么要领养这个孤儿进程?如果不领养孤儿进程,那么当这些进程退出时,没有进程可以为其回收,释放系统资源,当这些进程越来越多,也就代表着系统中被占用的无用资源越来越多!所以必须要对孤儿进程进行领养,然后在其退出时将其资源释放回收。


到这里,linux 中常见的几个进程状态就已经交代完毕了,但是关于进程这个概念远远还没有结束。截止目前,我们知道了进程属性中的标识符(即 pid),知道了进程的状态(R, S, D, T, t, X, Z)。但是进程中还有一个 优先级 的概念,同样是进程中相当重要的组成信息,也会在之后的文章中进行介绍。

如果感觉该篇文章给你带来了收获,可以 点赞👍 + 收藏⭐️ + 关注➕ 支持一下!

感谢各位观看!

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

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

相关文章

SpringBoot简单项目(二维码扫描)

pom.xml中导入依赖 <!-- zxing --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.3.0</version></dependency><dependency><groupId>com.google.zxing</gro…

探索七款前沿UI设计软件:创新与实践

之前我们分享了制作原型的有用工具。制作完原型后&#xff0c;我们需要优化界面&#xff0c;这就是 UI 设计师的任务了。UI 设计软件对设计师来说非常重要。UI 设计工具的使用是否直接影响到最终结果的质量&#xff0c;所以有人会问&#xff1a;UI 界面设计使用什么软件&#x…

Java批量查询CSDN质量分

文章目录 前言代码实现pom.xml实体类工具类质量分查询 效果开源仓库 前言 在CSDN平台申请“专家博主”、“优质创作者”等称号的时候&#xff0c;往往会对博客的质量分有一定的要求&#xff0c;这时候我们需要审视以往所发表的博客&#xff0c;找出质量分较低的博客&#xff0…

nordic 蓝牙ble 配对绑定的流程 原理

目录 配对和绑定的基本概念 配对和绑定的流程 1. 配对请求和响应 2. 配对方法选择 3. 密钥生成和交换 4. 配对完成和绑定 配对和绑定的代码实现 初始化Peer Manager 处理Peer Manager事件 处理BLE事件 启动广播 在Nordic芯片上实现蓝牙低功耗(BLE)设备的配对和绑定…

Python 为Excel单元格设置填充\背景色 (纯色、渐变、图案)

在使用Excel进行数据处理和分析时&#xff0c;对特定单元格进行背景颜色填充不仅能够提升工作表的视觉吸引力&#xff0c;还能帮助用户快速识别和区分不同类别的数据&#xff0c;增强数据的可读性和理解性。 本文将通过以下三个示例详细介绍如何使用Python在Excel中设置不同的单…

sql注入——sqlilabs1-15

目录 sql注入靶场练习--sqlilabs 1.less-1​编辑 1.测试发现单引号为逃逸符号 2.确定查询列数为三列 3.查询到数据库名 4.查询数据库中的表名 5.查询用户表的列名字 6.查询用户信息 2.less-2​编辑 2.确定查询列数为三列 3.查询到数据库名 4.查询数据库中的表名 5.…

机械学习—零基础学习日志(高数23——无穷小运算)

零基础为了学人工智能&#xff0c;真的开始复习高数 这段时间&#xff0c;把张宇老师讲解考研的第一部分基本全部学习完毕了。 这里把第一部分的内容最后汇总一下。 无穷小运算——吸收律 这里展示一些无穷小的具体计算思路 无穷小运算——计算方法 泰勒展开的原则 夹逼准则…

SQL报错注入之floor

目录 1.简述 2.关键函数说明 1.rand函数 2.floor&#xff08;rand&#xff08;0&#xff09;*2&#xff09;函数 3.group by 函数 4.count&#xff08;*&#xff09;函数 3.报错分析 4.报错流程 4.1寻找注入点 4.2爆数据库名 4.3爆表名 4.4爆字段名 4.5查询数据 1.…

PySide入门实战之五 | 信号与槽函数之鼠标、键盘等事件

&#x1f680;&#x1f680;&#x1f680; Pyside6实战教程专栏目录入口&#xff1a;点击跳转 目录 一、前期准备二、鼠标触发事件鼠标拖动窗口 一、前期准备 我们采用Pyside入门实战之四中通过QTDesigner创建的界面&#xff0c;具体由两个Label和一个Button组件构成&#xff…

【c++】基础知识——快速入门c++

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;C 目录 前言 一、手搓一个Hello World 二、命名空间namespace 1.命名空间的定义 2.命名空间的使用 3.命名空间补充知识 三、c中的输入和输出 四、缺省参…

图书馆座位再利用小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;座位信息管理&#xff0c;座位预订管理&#xff0c;互勉信息管理&#xff0c;意见反馈管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;我的 开发…

Unity补完计划 之Tilemap

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正 1.Tilemap 是什么 Q&#xff1a;和 SpriteShape有什么区别&#xff1f; A&#xff1a;tilemap强项在于做重的复背景&…

VsCode无法远程调试

一、问题描述 按照《VsCode gdb gdbserver远程调试C程序》中介绍的方法&#xff0c;配置好VsCode后&#xff0c;按下F5快捷键&#xff0c;或点击“Start Debugging”按钮&#xff0c;没有反应&#xff0c;无法启动调试&#xff1a; 二、解决方法 针对该问题&#xff0c;我尝…

常用设计模式总结

代码的评判角度 常见的评判代码好坏的词汇&#xff1a; 灵活性&#xff08;flexibility&#xff09;、可扩展性&#xff08;extensibility&#xff09;、可维护性&#xff08;maintainability&#xff09;、可 读性&#xff08;readability&#xff09;、可理解性&#xff08;…

电子元器件—三极管(一篇文章搞懂电路中的三极管)(笔记)(面试考试必备知识点)

三极管的定义及工作原理 1. 定义 三极管&#xff08;Transistor&#xff09;是一种具有三层半导体材料&#xff08;P-N-P 或 N-P-N&#xff09;构成的半导体器件&#xff0c;用于信号放大、开关控制和信号调制等应用。三极管有三个引脚&#xff1a;发射极&#xff08;Emitter…

Javascript——NaN有什么用法

简介 在 JavaScript 中&#xff0c;NaN&#xff08;Not a Number&#xff09;是一个特殊的值&#xff0c;用来表示非数字的结果&#xff0c;例如一个不合法的数学运算的结果。根据 IEEE 754 浮点数标准&#xff0c;NaN 不等于任何值&#xff0c;包括它自己。这意味着 NaN 是唯…

JAVA毕业设计158—基于Java+Springboot的二手车交易管理系统(源代码+数据库+万字论文+ppt)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringboot的二手车交易管理系统(源代码数据库万字论文ppt)158 一、系统介绍 本项目前后端不分离(可以改为ssm版本)&#xff0c;分为用户、管理员两种角色 1、用户&#…

Golang | Leetcode Golang题解之第326题3的幂

题目&#xff1a; 题解&#xff1a; func isPowerOfThree(n int) bool {return n > 0 && 1162261467%n 0 }

AXS4054:单节锂电池充电管理芯片特性与应用推荐

AXS4054是一款单节锂离子电池恒流/恒压线性充电器&#xff0c;芯片集成功率晶体管&#xff0c;充电电流可以用外部电阻设定&#xff0c;蕞大持续充电电流可达600mA,非常适合便携式设备应用&#xff0c;适合USB电源和适配器电源工作&#xff0c;内部采用防倒充电路&#xff0c;不…

鸿蒙AI功能开发【拍照识别文字】

拍照识别文字 介绍 本示例通过使用ohos.multimedia.camera (相机管理)和textRecognition&#xff08;文字识别&#xff09;接口来实现识别提取照片内文字的功能。 效果预览 使用说明 1.点击界面下方圆形文字识别图标&#xff0c;弹出文字识别结果信息界面&#xff0c;显示当…