进程状态

举报
跳动的bit 发表于 2022/08/30 07:44:57 2022/08/30
【摘要】 💦 进程状态 1、Linux 2.6内核源码后期我们主要也是以 Linux 2.6 为主来学习,因为它匹配的书籍较多。其中 task_state_array[] 里描述的是 Linux 的进程状态: 2、R (running)进程是 R 状态,一定在 CPU 上运行 ❓  进程在运行队列中,就叫做 R 状态,也就是说进程想被 CPU 运行,前提条件是你必须处于 R 状态,R :我准备好了...

💦 进程状态

1、Linux 2.6内核源码

后期我们主要也是以 Linux 2.6 为主来学习,因为它匹配的书籍较多。

其中 task_state_array[] 里描述的是 Linux 的进程状态:
在这里插入图片描述

2、R (running)

进程是 R 状态,一定在 CPU 上运行 ❓

  进程在运行队列中,就叫做 R 状态,也就是说进程想被 CPU 运行,前提条件是你必须处于 R 状态,R :我准备好了,你可以调度我。

为啥我在跑,但状态却是 S ❓

在这里插入图片描述

在这里插入图片描述

  因为代码大部分时间是在 sleep 的,且每次 1 秒钟,其次 printf 是往显示器上输出的,涉及到 I/O,效率比较低,一定会要求进程去等我们把数据刷新到显示器上。所以综合考量,我们这个程序可能只有万分之一的时间在运行,其它时间都在休眠,站在用户的角度它是 R,但是对于操作系统来说它不一定是 R,它有可能在队列中等待调度。

如果我们就想看下 R 状态呢 ???

循环里啥都不要做。

在这里插入图片描述

在这里插入图片描述

3、S (sleeping)

休眠状态(浅度休眠,大部分情况)。这种休眠是可被换醒的,我们可以 Ctrl + C 退出循环,而此时的进程就没了,也就是说它虽然是一种休眠状态,但是它随时可以接收外部的信号,处理外部的请求。

在这里插入图片描述

4、D (disk sleep)

休眠状态(深度休眠)
在这里插入图片描述

  此时进程拿着一批数据找到了磁盘说:磁盘,你帮我把数据放在你对应的位置。磁盘说:好嘞,然后磁盘就慢慢地写到对应的位置。此时进程处于等待状态,它在等把数据写完,然后告诉进程写入成功 or 失败。此时操作系统过来说:你没发现现在内存严重不足了吗,我现在要释放一些闲置的内存资源,随后就把进程干掉了。磁盘写失败后,然后跟进程说:不好意思,我写失败了,然而进程已经挂了,此时我们的数据流向就不确定了。

对于上面的场景,这个锅由谁来背 —— 操作系统/内存/磁盘 ❓

于是它们三方开始了辩论:

  操作系统说,你在那等,我又不知道你在等啥,系统内存不足了,我就尽我的职责,我的工程师就是这样写我的,杀掉闲置的内存。假如我这次不杀你,那你说下次我再遇到一些该杀死的闲置的内存,我怕我又被责怪,所以没杀,你就认为我不作为 ?操作系统说:我又识别不了哪些进程是重要或不重要的。

  磁盘说,我就是一个跑腿的,你们让我干啥就干啥,又不是写入的结果不告诉你,而是你不在了。

  进程说,我在那规矩的等着呢,是有人把我杀了,我自己也不想退出。

这里好像谁也没有错,但是确实出现了问题,你难道说错的是用户 —— 内存买小了吗 ?无论是操作系统、内存、磁盘都是为了给用户提供更好的服务。根本原因是操作系统能杀掉此进程,如果让操作系统不能杀掉此进程就可以了。我现在做的事情很重要,即便操作系统再牛,也杀不了我,你系统内存不够了,你想其它办法去,不要来搞我。所以我们针对这种类型的进程我们给出了 D 状态,所以操作系统从此就知道了以后 D 是个大哥,不能搞。

所以对于深度睡眠的进程不可以被杀死,即便是操作系统。通常在访问磁盘这样的 I/O 设备,进行数据拷贝的关键步骤上,是需要将进程设置为 D 的,好比 1 秒钟内,平台有 100 万的用户注册,如果数据丢失,那么带来的损失是巨大的。

对于深度睡眠的进程怎么结束 ???

  只能等待 D 状态进程自动醒来,或者关机重启,但有可能会卡住。深度睡眠的进程我们没法演示,万一把自己的机器玩挂了,成本较高。

不管是浅度睡眠还是深度睡眠都是一种等待状态,因为某种条件不满足。

5、T (stopped)

对于一个正在运行的进程,怎么暂停 ❓

在这里插入图片描述

使用 kill -l 命令,查看信号,这里更多内容后面我们再学习:

在这里插入图片描述

使用 kill -19 27918 命令,给 27918 进程发送第 19 号信号来暂停进程:

在这里插入图片描述

使用 kill -18 27918 命令,给 27918 进程发送第 18 号信号来恢复进程:

在这里插入图片描述

我们也可以认为 T 是一种等待状态。

6、T (tracing stop)

  当你使用 vs of gdb 调试代码,比如你打了一个断点,然后开始调试,此时在断点处停下来的状态就是 t,这里是为了和上面进行区分。这里先不细谈。

7、Z (zomble)

  比如你早上去晨跑时,突然看到其他跑友躺地上,你虽然救不了人,也破不了案,但是作为一个热心市民,可以先给 120 打电话,再给 110 打电话。随后警察来了,第一时间肯定不会把这个人抬走,清理现场,如果是这样的话凶手肯定会笑开花,第一时间肯定是先确定人是正常死亡还是非正常死亡,如果是非正常死亡,那么立马封锁现场,拉上警戒线,判断是自杀的还是他杀。随后 120 来了,对人的状态进行判断,如果是正常死亡,就判断是因为疾病,还是年纪大了。最终判断出人是是因为疾病离开的,警察和医生的任务已经完成后,不会就把人放这,直接撤了。而是把人抬走,恢复地方秩序,然后通知家属。所以当一个人死亡时,并不是立马把这个人从世界上抹掉,而是分析这个人身上的退出信息,比如说体态特征、血压等信息来确定具体的退出原因。
  同样进程退出,一般不是立马让 OS 回收资源,释放进程所有的资源,作为一个死亡的进程,OS 不会说你已经死了,就赶紧把你拉到火葬场,而是 OS 要知道进程是因为什么原因退出的。创建进程的目的是为了完成某件任务,进程退出了,我得知道他把我任务完成的怎么样了,所以 OS 在进程退出时,要搜集进程退出的相关有效数据,并写进自己的 PCB 内,以供 OS 或父进程来进行读取。只有读取成功之后,该进程才算真正死亡,此时我们称该进程为 死亡状态 X,。其中我们把一个进程退出,但还没有被读取的那个时间点,我们称该进程为 僵尸状态 Z
  我作为父进程 fork 创建一个子进程,子进程死亡了,但父进程没通过接口让 OS 回收,此时子进程的状态就是 Z。

僵尸状态演示 ❓

在这里插入图片描述

这里我们可以写一个监控脚本 while :; do ps ajx | head -1 && ps ajx | grep mytest; sleep 1; echo "####################"; done 来观测:

在这里插入图片描述

8、X (dead)

  参考 Z 状态。其次 X 状态我们看不到,因为我们释放了,它是一瞬间的。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。