进程状态(二)----- linux 中具体的进程状态(上)

news2025/1/23 12:14:49

目录

  • 前言
  • 1. R 状态
  • 2. S 状态
  • 3. D 状态

前言

继上一篇文章 进程状态(一)---- 运行,阻塞,挂起 介绍了操作系统都有的三个进程状态,而这篇文章则是将进程状态具象化,谈论具体到 linux 系统中的进程状态都有哪些。

/*
* 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. R 状态

既然要了解某一种状态,那么肯定要先见一见吧。亮出我们的测试 demo

int main()
{
    while(1)
    {
     	cout << "hello, linux! \n";
        sleep(1);
    }
    return 0;
}

在这里插入图片描述

很奇怪的是,按照我们正常的理解,我们明明已经将这个程序运行起来了,这个进程也一直在执行中。但是,查到的状态确实 S+,而并不是 R 状态!

int main()
{
    while(1);
    return 0;
}

在这里插入图片描述

而当我们执行这一份代码的时候,就会发现,这个进程运行起来的时候,检测到的状态是 R+ 状态!(这里先解释一下,+ 号的含义是前台运行,而不带 + 号则代表该进程处于后台运行,前台运行可以理解为,如果此刻你不关闭这个进程 或者将进程转为后台工作,在命令行中你是无法执行其它指令的。后台运行类似 ./test &

所以这种想象是为什么呢??这个进程明明正在执行,但是却出现了两种截然不同的状态! ---- 原因就是第一个 demo 里面涉及到了打印操作,那么它就需要访问外设资源,也就是往显示器进行写入。但是,现在的问题就在于,外设不一定一直处于就绪状态,所以对于进程而已,它其实很大概率一直处于一个等待外设资源的状态!而在上一篇文章,我们说了,进程在等待某种外设资源的时候,称为阻塞状态!而当我们把 cout 去掉之后,不再需要进行 IO 操作了,就是纯粹的条件判断,这是 cpu 需要做的工作,所以这个进程就一直处于死循环的判断中,检测到的状态就是 R 状态,即运行状态!

2. S 状态

那在 linux 中什么是 S(睡眠) 状态呢?在介绍 R 状态的时候,误打误撞的发现了一个正常运行的进程,处于 S 状态,但是那个例子还不足生动的解释什么是 S 状态。

int main()
{
    int a;
    cout << "Enter: ";
    cin >> a;
    cout << a << endl;
    return 0;
}

在这里插入图片描述

如图,当我进行 scanf 或者 cin 读取键盘数据时,但是我现在就是迟迟不输入,不回车,那么进程此刻就一直处于等待键盘设备资源的状态!而这个状态与介绍 R 状态时的等待外设资源是一样的,只不过上面那个案例,进程一直在运行,给我们的直观感受就是 R 状态,只不过是因为 cpu 与 外设的速度达到的 10^6 量级,这么大的差距下,进程 99.99999% 都是在等待外设资源,只有那 0.0000001% 是在被 cpu 执行(处于 R 状态),而现在这个案例,只不过是干脆将进程卡住了,只要我们不输入,它就会一直处于等待键盘设备资源中,而进程被卡着不被执行,处于等待某种资源状态,在操作系统中,我们称为阻塞状态,而具体到 linux 系统中,这种阻塞状态就是 S 状态!

3. D 状态

在前言部分的 linux 源码中,我们就看到了 S 是 sleep,D 也是 sleep(disk sleep),那这两种都是睡眠状态,有什么区别吗?? ---- 字面上的区别就是,D 是深度睡眠(也称为磁盘休眠),那么既然有深度睡眠,你也可以将 S 解读为 浅度睡眠。

而上面所展现出来的 S 状态的进程,它们都是可以被唤醒的(只要等待资源就绪了,立马就可以被唤醒),同时它也是可以被 kill -9 杀掉的。既然都是睡眠,D 状态肯定要与 S 状态不同,所以不同点在哪呢?我们讲个故事。。。

假设今天内存中有一个进程,它现在正在尝试往磁盘写入 500M 的数据,所以进程就呼喊了在远处的磁盘 “磁盘,我这有 500M 的数据,你帮我写一下”,磁盘听到进程的呼唤后 “行,你把数据给我吧”,之后磁盘就去找一个足够容量 500M 数据的位置,把数据给进程写入到磁盘中,写完之后再把结果回去反馈给进程(写入成功还是失败)。而磁盘写入,是需要时间的,换句话说,在磁盘写入的过程中,进程是需要等待磁盘的,等磁盘把数据都写完了,然后拿到磁盘的反馈结果之后,再去干其它的工作。所以磁盘在写入的时候,进程就在内存中翘着腿,喝着茶,嘴里还哼着歌。。。

很不巧,现在计算机因为各种原因处于高负载状态,系统进程非常多,系统中的内存资源严重不足了,操作系统正在忙的焦头烂额,正在绞尽脑汁的腾出内存资源,操作系统把所有可以置换的进程都置换了(处于等待队列中的进程,将这些进程所对于的代码和数据换出到磁盘中),内存资源还是处于不足状态,突然间路过看到内存中有一个翘着腿、喝着茶,嘴里还哼着歌的空闲进程!

而此时,操作系统中的内存资源越来越吃紧了,操作系统心理也憋着一股气 “我tm在这累死累活想办法腾出内存资源,你不仅占用我资源,还在这啥都不干,给我gun!”,于是操作系统直接把这个进程杀掉了。而进程被杀掉之后,磁盘写入到一半发现没空间了,于是想回来找到进程,并且将结果反馈给进程。但是,磁盘此刻傻眼了,因为哪还有它要找的那个进程。磁盘心理想着 “so?爱会消失吗?说好的你等我?”,磁盘也不知道怎么办了,因为它只是负责写入数据,它并不知道该如何决策这件事啊。

而面对上述情况,不同的硬件的做法可能都不一样,大部分的硬件都是选择直接丢弃数据。很不幸,这波数据存储着银行上百万条转账记录,价值高达10个亿,于是法官出面了,而众多舆论都直接指向了操作系统,大家都认为是操作系统杀掉了进程才导致的悲剧。

所以操作系统就出面询问了法官 “ 请问用户是不是赋予我管理软硬件资源的权力了?请问我杀掉进程是不是在极端情况下做的?请问我这是不是在履行我自己的义务?我总不能因为这一个进程,导致操作系统奔溃了,最终所有的进程都挂掉了吧?操作系统都挂了,那其它进程的数据还是会丢,那这样损失岂不是更大?”

法官听闻,点了点头(有道理),于是法官就看了一眼磁盘 “数据是你写的,数据也是你丢的, 你有什么想说的吗?”

磁盘顿时抖了个机灵 “法官大人,我只是一个跑腿的啊,人家叫我干嘛,我就干嘛,进程叫我帮它把数据写了,我告诉它在那等我消息,而我回来之后我找不到进程了啊,但是我的工作模式就是这样的,写入失败了,进程又不在了,我怎么知道这些数据我要怎么办呢?如果今天我有罪,那么岂不是所有的磁盘都有罪。”

法官听闻也是点点头(这货说的也有道理),于是法官大家想着,既然操作系统没错,磁盘也没错,那有错的总得是你进程了吧?

进程心理一百只马路过,“我明明是受害者,我都被杀掉了,现在我还有错了?天理不容啊!”

法官听闻陷入了沉思,好像大家说的都没问题。

所以因为可能存在上述情况,于是操作系统在设计的时候,就规定了只要某一个进程当前有写入任务,并且无法一时间得到磁盘的响应,需要进程等待,这个进程不能以浅度睡眠(即 S 状态)存在于操作系统中,需要将其设置为 D 状态,并且规定,任何人(包括操作系统),不得以任何理由杀掉正在处于 D 状态的进程。

所以!当进程处于等待磁盘写入时,此时进程所处的状态为 disk sleep,即 D 状态!

但是你要知道的是,D 状态代表着 高 IO,在系统中哪怕出现一个 D 状态的进程,你的操作系统就已经快要奔溃,而当被用户发现系统中有一个 D 状态的进程,就说明这个状态已经维持了一段时间了,用户的感知级别是 秒为单位的,而慢如磁盘等外设,怎么说也是毫秒,cpu 更是以纳秒为单位,因此如果到了连用户都能察觉的程度,你的系统八九不离十,距离奔溃就只差几个呼吸了。所以一般情况下,就算有 D 状态的进程,维持时间也是很短的。


由于篇幅过长等问题,linux 中还有关于进程的其它三个状态,分别是 T && t 状态,X 与 Z 状态,还有所谓的僵尸进程,孤儿进程,这些状态之间都有什么不同,在下一篇文章 进程状态(三)----- linux 中具体的进程状态(下) 都会进行一一介绍。

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

感谢各位观看!

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

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

相关文章

Geoserver源码解读七 插件(二)扩展图层预览界面

系列文章目录 Geoserver源码解读一 环境搭建 Geoserver源码解读二 主入口 Geoserver源码解读三 GeoServerBasePage Geoserver源码解读四 REST服务 Geoserver源码解读五 Catalog Geoserver源码解读六 插件&#xff08;怎么在开发模式下使用&#xff09; 目录 系列文章目录…

vector中 resize()和reserve()

1.resize()改变容器大小 resize除了预留内存以外&#xff0c;还会调用容器元素的构造函数&#xff0c;不仅分配了N个对象的内存&#xff0c;还会构造N个对象。从这个层面上来说&#xff0c;resize()在时间效率上是比reserve()低的。 2.reserve()容器大小管理 用于预留内存。 …

【Linux】shell命令与Linux权限的概念

目录 一、shell命令二、Linux权限的概念2.1 Linux权限的概念2.1.1 用户2.1.2 指令2.1.2.1 su指令2.1.2.2 sudo指令 2.2 Linux权限管理2.2.1 文件访问者的分类&#xff08;人&#xff09;2.2.2 文件类型和访问权限&#xff08;事物属性&#xff09;2.2.2.1 文件类型2.2.2.2 基本…

C++ 中迭代器的first和second

c 里面的map容器的迭代器里面 有个first 和 second&#xff0c;分别指向键值和数值 it.first就是在迭代器中获取map键值&#xff0c;it.second同理 #include<iostream> #include<map> using namespace std;int main(void){map<string, string> m;//新建一个m…

lower_bound函数和upper_bound函数

lower_bound 和 upper_bound 函数都是 C 标准库算法&#xff0c;用于在已排序的范围内查找元素。它们返回的是迭代器&#xff0c;指向满足特定条件的元素位置。 lower_bound(begin, end, val) 功能&#xff1a;返回指向第一个不小于 val 的元素的迭代器。含义&#xff1a;如果…

如何快速下载拼多多图片信息,效率高

图片是电商吸引顾客的关键因素&#xff0c;高质量的商品图片能提升产品吸引力&#xff0c;增强用户购买欲望。良好的视觉展示有助于建立品牌形象&#xff0c;提高转化率。同时&#xff0c;图片也是商品信息的主要传递媒介&#xff0c;对消费者决策过程至关重要。 使用图快下载器…

Linux内核有什么之块设备驱动有什么第七回 —— 邂逅的三个文件系统之二:实际文件系统(4)

接前一篇文章&#xff1a;Linux内核有什么之块设备驱动有什么第六回 —— 邂逅的三个文件系统之二&#xff1a;实际文件系统&#xff08;3&#xff09; 本文内容参考&#xff1a; 《Linux设备驱动开发详解 —— 基于最新的Linux4.0内核》 宋宝华&#xff0c;机械工业出版社 3…

奥运会大规模使用中国AI大模型!

B站&#xff1a;啥都会一点的研究生公众号&#xff1a;啥都会一点的研究生 AI圈最近又发生了啥新鲜事&#xff1f; 巴黎奥运会大规模使用中国 AI 大模型 巴黎奥运会成为一场科技与体育的盛宴&#xff0c;其中包括了大量中国科技的应用。AI 技术将在多个方面发挥作用&#xf…

《计算机网络》(第8版)第7章 网络安全 复习笔记

第 7 章 网络安全 一、网络安全问题概述 1 计算机网络面临的安全性威胁 计算机网络上的通信面临两大类威胁&#xff0c;即被动攻击和主动攻击。 &#xff08;1&#xff09;被动攻击 这是指攻击者从网络上窃听他人的通信内容&#xff0c;通常把这类攻击称为截获。 &#xff08…

2.外部中断(EXTI)

理论 NVIC&#xff1a;嵌套向量中断控制器&#xff08;解释教程&#xff09; 外部通用中断线(EXTI0~EXTI15)&#xff1a;每个GPIO设置成中断模式&#xff0c;与中断控制器连接的线 外部中断触发方式 上升沿触发、下降沿触发、双边沿触发 外部中断触发函数 在stm32f1xx_it.c文件…

【AI作图:奥运会游泳冠军】

画一个&#xff1a;水花&#xff0c;上半身&#xff0c;游泳冠军&#xff0c;泳池背景&#xff0c;面部明亮&#xff0c;眼神光&#xff0c;亚洲运动员&#xff0c;超高品质&#xff0c;真人&#xff0c;完美容颜&#xff0c;健美&#xff0c;健身&#xff0c;身材娇好&#xf…

Jackson常用注解详解

Hi &#x1f44b;, Im shy 有人见尘埃&#xff0c;有人见星辰 Jackson常用注解详解 文章目录 Jackson常用注解详解0. 引入依赖1. JsonProperty2. JsonIgnore3. JsonFormat4. JsonInclude5. JsonCreator6. JsonValue7. JsonIgnoreProperties结论 Jackson是Java生态系统中广泛…

例题:使用一条命令将xxx目录下除了xx子目录之外的文件全部删除(find、管道、grep、exec)

文章目录 例题&#xff1a;删除xx子目录以外的所有目录和文件需求方式一方式二 例题&#xff1a;删除xx子目录以外的所有目录和文件 需求 使用一条命令将/opt目录下除了rh子目录之外的文件全部删除 [rootlocalhost opt]# cp /var/log/vm* /opt/ [rootlocalhost opt]# mkdir …

(一)循环依赖,你真的懂了吗?万字解析循环依赖底层原理 - 什么是Bean循环依赖?Spring是如何解决的?二级缓存可以解决吗?遇到相关报错如何处理?

theme: vuepress 一、相关知识点简介 Spring Boot是基于Spring框架的一个快速开发平台&#xff0c;旨在简化Spring应用的创建和部署。通过提供一系列开箱即用的默认配置和自动化工具&#xff0c;Spring Boot使开发者能够专注于业务逻辑&#xff0c;而无需处理复杂的配置和依赖…

【Python机器学习】支持向量机——在复杂数据上应用核函数

上图中&#xff0c;数据中存在某种可以识别的模式&#xff0c;其中一个问题就是&#xff1a;我们能否想线性情况一样&#xff0c;利用强大的工具来捕捉数据中的这种模式&#xff1f; 利用核函数将数据映射到高维空间 在上图中&#xff0c;数据点处于一个圆中&#xff0c;人类…

《零散知识点 · 自定义 HandleMapping》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

[独家原创] CPO-RBF多特征分类预测 优化宽度+中心值+连接权值 (多输入单输出)Matlab代码

[独家原创] CPO-RBF多特征分类预测 优化宽度中心值连接权值 &#xff08;多输入单输出&#xff09;Matlab代码 目录 [独家原创] CPO-RBF多特征分类预测 优化宽度中心值连接权值 &#xff08;多输入单输出&#xff09;Matlab代码效果一览基本介绍程序设计参考资料 效果一览 基本…

算法--初阶

1、tips 1.1、set求交集 {1,2,3} & {2,3} & {1,2} {2} 其实就是位运算&#xff0c; 只有set可以这样使用&#xff0c; list没有这种用法 {1,2,3} | {2,3, 4} | {1,2} {1, 2, 3, 4} 并集 1.2、*与** * 序列(列表、元组)解包&#xff0c;如果是字典&#xff0c;那…

15.75.【C语言】表达式求值

目录 一.整型提升 1.定义 2. 一.整型提升 1.定义 C语言中整型算术运算总是至少以缺省&#xff08;默认&#xff09;整型类型的精度来进行的。为了获得这个精度&#xff0c;表达式中的字符和短整型操作数在使用之前被转换为普通整型&#xff0c;这种转换称为整型提升 2.整型提…

C++初学者指南-5.标准库(第二部分)--移除元素算法

C初学者指南-5.标准库(第二部分)–移除元素算法 文章目录 C初学者指南-5.标准库(第二部分)--移除元素算法remove / remove_ifremove_copy / remove_copy_ifunique / unique_copyerase / erase_if相关内容 不熟悉 C 的标准库算法&#xff1f; ⇒ 简介 remove / remove…