文章目录
认识进程状态
上面就是各种进程状态,上面都是理论进程状态理论进程状态放在哪个操作系统中都是正确的,但是具体的操作系统实现可能又会有所不同。
下面我们来理解进程状态:
其实进程状态就是进程PCB结构体中定义的一个status变量,我们知道改变status就是改变进程的状态。
新建
字面意思,进程刚刚被创建的状态。
运行
task_struct结构体在运行队列中排队的情况,就叫做运行状态。
有人会有疑问task_struct结构体只是在排队又不是正在被执行,怎么能叫做运行态呢?
例子理解:
比如张三在食堂排队准备吃饭,这是他的舍友李四打电话过来问张三你在干嘛,张三会说我在吃饭啊。
这时候张三正在吃放吗?并没有只是在排队。这也就理解了上面的问题。
阻塞
等待非CPU资源就绪的状态就叫阻塞状态。
系统中一定是存在各种资源的,不仅仅是CPU资源,还有网卡、磁盘、显卡等其它设备。
我们使用CPU资源就需要运行队列,所以可想而知OS中一定不仅仅值存在一种队列。
例子:
运行结果:
我们可以看到,程序一直在等我们键盘输入数据,如果我们一直不输入数据,就是等待键盘数据资源就绪。而这个进程的状态就是阻塞状态。
挂起
当内存开不足的时候,OS操作系统会将长时间不执行的进程代码和数据换出到磁盘中。也就是SWAP分区中。
所以我们自己安装系统的时候,一般我们会自动分出一个SWAP分区。
例子理解:
假设你们学校旁边发生了山体滑坡,而国家排军队来帮助周边村民保护各种财产。但是这些士兵没有地方住,于是你们学校被政府告知要安排这些士兵的住处,但是学校宿舍不够,于是校领导安排你们先回家,等灾情结束士兵们离开你们再回来。
那么你们离开学校相当于被学校开除了吗?
当然不是,你们的个人信息还在学校的教务处中,你们知识肉体离开了学校。
所以同理推广到挂起。 挂起的时候进程的PCB结构体还在内存中,只不过代码和数据被放入到SWAP分区中了。
结论:当内存不足的时候,OS通过适当的置换进程的代码和数据到磁盘中,这个进程的状态就叫挂起。
Linux具体的进程状态
循环监测进程指令:
bash
while :; do ps axj | head -1 && ps axj | grep mytest | grep -v grep; sleep 1; echo "########################"; done
R
R:运行状态
演示:
运行代码,监测进程:
我们运行代码的时候监测进程,我们发现进程是S状态,这是为什么呢?不应该是R状态吗?因为printf()需要访问外设,而访问外设速度的慢所以需要等待外设资源就绪,所以就不是运行态。我们接下来把printf去掉看看进程状态。
我们发现此时进程的状态就变为R状态。
S
S:阻塞状态、等待状态、睡眠状态(可中断睡眠)
演示:
运行代码和监测:
我们看到,该进程为S状态。
这里我们看到不管是之前的R还是现在的S后面都跟了+号,那么这个+号表明什么意思呢?
+号说明该进程属于前台进程,在运行是输入任何指令都无效。
我们可以把前台进程变成后台进程,这样进程运行就不影响我们输入指令了。那么如何变成后台进程。
就比如下面这个死循环代码 ,正常情况下它会一直死循环一直占用窗口,我们不能输入任何指令,但是我们把它变成后台进程呢?
我们可以看到,还能输入指令并且进程还存在,只不过变为了后台进程。
D
D:磁盘睡眠,也被称为不可中断睡眠。
例子:
当我们进程需要向磁盘写入大量数据的时候,进程需要等待数据写入是否成功的结果。
假如当前服务器压力过大的时候,OS通过一定的手段,杀掉一些进程,来起节省空间的作用。可就在这时候进程A被杀掉了,这样就导致了大量的数据流失。
所以将这里的进程被设为D状态,并且告知操作系统D状态的进程一定不能杀掉。
dd命令能够演示D状态进程。
t
t:调试状态,当用gdb调试代码的时候,这个进程会被称为t状态。
演示:
T
T:暂停状态
我们可以看到T状态就是代码暂停,发送19号信号可以触发T状态,发送18信号可以恢复原状态。
我们可以看到确实恢复了。
X
X:终止 瞬时性非常强
当进程退出需要操作系统回收资源,而操作系统此时特别忙,进程就会暂时的进入X状态。
Z
Z:僵尸状态
是什么
例子:
假如张三有晨跑的习惯,今天张三正在晨跑,而此时李四飞一样的从张三面前跑过去。但是没跑出去多远,李四就倒在了路上,张三过去查看发现没呼吸和心跳了。于是张三打了120,和110没过多久120和110同时赶来。110立马封锁现场,120查看发现确实已经没救了。于是110立马请来法医调查死者死因,最后发现是经常不规律睡觉然后跑步猝死的。于是110立马通知死者家属,并且拉走死者一天。
上面例子可推广到进程:一个进程已经退出,但是还不允许被OS释放,处于一个被检测的状态,叫做僵尸状态。
为什么会不允许被OS释放呢?
因为父进程或者操作系统可能需要该进程的运行返回值或者其它返回结果,而父进程或者OS还在忙其它事情所以还不允许被释放。
那么该进程一般是谁回收的呢?
一般是父进程或者OS回收。
为什么
那么维持僵尸状态是为什么呢?
维持该状态是为了让父进程或者OS获取该进程运行结果和回收的。
代码演示僵尸进程:
运行:
本代码子进程运行几次就退出,而父进程一直在运行,所以子进程就一直处在僵尸状态。