快@你的好兄弟好姐妹来内卷进程状态

Posted 做1个快乐的程序员

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快@你的好兄弟好姐妹来内卷进程状态相关的知识,希望对你有一定的参考价值。

进程状态

1、什么是进程状态

1.1 进程概念和进程控制块

  各位读者要学习进程状态,相信已经对进程的概念有了初步了解,通俗来讲,进程就是运行起来的程序,是担当分配系统资源的实体。 操作系统为了对进程进行管理,除了将磁盘中的可执行程序加载到内存中,还会创建相关数据结构来管理进程,这个数据结构就是进程控制块-PCB,这里的PCB是对所有进程控制块的统称;Linux中的PCB是task_struct,而Windows中的PCB是EPROCESS。进程控制块PCB中存储着我们进程的各种各样的信息,其中就包括我们的进程状态。

1.1 进程状态的引出

  对于进程状态这个概念,可能大家之前比较陌生,但大家应该听说过创建、就绪、运行、阻塞、结束等名词,这五个就是进程的一些常见状态。但是这些状态不是具体的一款操作系统进程的状态,而是操作系统提取Linux、Windows、Mac等系统进程状态的共性总结出来的进程5大状态,因此操作系统也被称为计算机的哲学

  而我们今天是要具体到一款操作系统,学习一款操作系统中进程的具体状态,我们以Linux系统为例。

2、进程状态

2.1 进程状态的查看

  为了让各位读者对进程状态有一个概念上的理解,我们创建了Makefile和procstat.c两个文件,内容如下:

图一:Makefile
图二:procstat.c
  无非就是一个死循环程序,当我们运行起来,其结果无非就是死循环打印“proc is running!”,并休眠1s,此时我们另开一个终端窗口,输入命令查看系统中进程的相关信息,并将头部信息进行打印。我们发现头部信息有一列为STAT,STAT就代表了当前进程的状态。
图一:Makefile
图二:procstat.c
  通过上面的操作,我们可以推出这样的结论: 进程状态是可以抽象化成数据的,然后保存在进程控制块task_struct中。

2.2 进程的5种状态

2.2.1 R - 运行状态

  进程是R状态,不代表正在运行!代表可被调度。所以一个CPU,是可以同时存在多个R状态进程的。换言之,操作系统在调度的时候,只有R状态的进程才有可能被调度。下图中,我们给出了一个链表,链表中一个节点就代表一个进程的task_struct,task_struct中存放着进程的进程状态:我们的操作系统只需要找到描述进程状态的task_struct,就可以获取到每个进程的状态。

  但是操作系统要想找出状态为R的进程,就要遍历链表,而遍历链表本身就是一个O(N)时间复杂度的事情。所以操作系统在系统内部,除了将所有PCB组织成双链表,保证我们可以找到进程之外,操作系统还会维护一个概念—调度队列。即系统中所有处于R状态的进程都会被链接起来,形成一个队列。操作系统在进程调度的时候直接找这个队列就可以了,按照相应的算法调度进程。比如:FIFO先来先服务等。

  我们想要实际观察到进程的状态,此时我们修改上面procstat.c的代码。此时我们就观察到了进程的R状态。

图一:procstat.c
图二:运行结果
图三:进程查询结果

2.2.2 S - 浅度睡眠状态

  我们继续修改代码,查询相应的进程,发现procstat的STAT状态为S+,即休眠状态。我们通常将Linux下的休眠状态称为浅度睡眠,一般用来进程等待某种事件发生。浅度体现在该进程可以随便被唤醒,甚至可以直接被杀掉。

图一:procstat.c
图二:进程查询结果

2.2.3 D - 深度睡眠状态

  我们无法演示深度睡眠状态,但是该状态是的的确确存在的,我们举一个例子来帮助各位读者理解。
  进程A的任务是有数据过来时往磁盘存数据,进程B的作用是将数据传输给进程A,但是此时数据为10G,存取到磁盘需要很长时间,并且进程B是要清楚进程A是否将数据成功存储。

  在整个数据转移过程中。进程B等待过程属于S状态,而此时系统很忙,操作系统OS清理闲置进程,进程B就被杀死,但是进程A存储失败,不知道是否继续存储还是清掉部分内容再存储。所以导致出错,但是他们三个部分各自做各自的工作,谁都没有错。所以此时就有了D状态。D状态表示该进程不会被杀掉,即便你是操作系统。要么计算机重启,要么自动唤醒,才可以恢复。

2.2.4 T - 停止状态

  我们kill -l就可查看信号的列表,可以看到总共有62个信号,其中1-31属于普通信号,34-64属于实时信号。我们是可以向某一正在运行的进程发送暂停信号的,收到暂停信号的进程就会进入暂停状态,关于信号的知识点小编会在后续的文章中进行补充,这里不是重点,知道即可。暂停信号的编号是19,SIGSTOP。

  我们修改代码,此时代码为死循环打印,此时我们查询进程的状态,当程序运行时,程序始终处于S+状态,这个地方可能就有同学疑问了,我的程序明明在死循环打印,为什么还是处于S状态呢?我们在procstat.c文件中调用了输出函数,该函数是往外设—显示器上输出信息,而我们的CPU是很快的,所以大部分的工作时间不是CPU向缓存池输入数据,而是内存向外设-显示器输出,所以进程大部分时间仍然处于休眠。因为外设太慢了。
  当我们向正在运行的进程发送SIGSTOP命令后,该进程的状态变为T状态。

图一:procstat.c
图二:进程查询结果
  处于T状态的进程是可以重新被唤醒的,我们向处于暂停T状态的进程发送18号信号-SIGCONT命令,此时进程被重新唤醒。

这里需要注意的是,T状态和S状态是有区别的:
  休眠本质上是一种挂起状态。
  暂停意味着暂时不跑。
  S状态可能是为了等待某种需求,而T状态可能就是单纯的想让一个进程暂停。

2.2.5 X - 死亡状态

  X状态我们也是无法进行模拟的,这个状态只是一个返回状态,我们用户不会在人物列表中看到这个状态。此时表示该进程已经完成工作,系统为其申请的各种资源也已被释放。

结束语:读了这篇文章有没有对你有帮助呢?还不快分享给你的好伙伴一起学习!除了这5种,还有僵尸进程、孤儿进程、守护进程,小编会在后续文章中持续分享,我们共同进步!

以上是关于快@你的好兄弟好姐妹来内卷进程状态的主要内容,如果未能解决你的问题,请参考以下文章

《用微信测试公众号慰问你的好兄弟/姐妹》:用java简单实现微信公众号消息推送(入门且详细且有效)

从另一个组件更新组件状态的最简单方法是啥?可以说组件是兄弟姐妹吗?

在 SwiftUI 中的兄弟姐妹之间从父级共享状态

如何让 React 中的 onClick 处理具有多个兄弟姐妹的单个元素?

什么是PHP?

哪位兄弟姐妹怎么在SAP/ABAP的表BKPF中增加自定义字段怎么做