【Linux】进程状态

目录

操作系统层面的状态

Linux中具体的状态

running/sleeping状态

disk sleep状态

stopped状态

tracing stop状态

僵尸进程与孤儿


我们之前说了进程,进程也是有状态的,这也是好理解的,因为进程不可能一直在CPU中跑着,当进程在CPU运行时或者在运行队列中我们都叫运行状态,有运行状态就有其他状态,比如后面要说的阻塞挂起。为什么要有状态呢?因为当前的状态决定了进程后续的动作
进程需要排队一定是因为在等待某种软硬件资源,它可以在CPU运行队列中,它要等待CPU执行;它也可以等待比如键盘资源,比如scanf就要等待键盘写入东西。并且只要是排队,一定是进程的task_struct在排队,并且我们的一个task_struct可以连接到多个队列中,它的具体实现方式就是创建一个链表节点的对象,放多个这样的对象的到PCB中,然后有了链表的节点再通过计算偏移量的方式找到整个PCB。

操作系统层面的状态

那我们下面先来谈一谈操作系统层面的进程状态,然后再具体谈Linux这款操作系统都有什么状态

首先是运行状态,我们要知道一个CPU就有一个运行队列,所以进程之间是要排队的,而不管是在运行中还是在CPU处排队,我们都叫运行状态。因为CPU执行一个进程是很快的,比如1ms,那么十个排队的进程在1s内就会每个被执行100次,在CPU看来确实是间断的,但是在我们看来就是连续的,这也就是是为什么我们的电脑只有一个CPU,但是当我们同时打开多个软件时它们就好似在同时运行的原因了。

下面一个是阻塞状态,所谓阻塞就是停滞不前了,为什么呢?因为它要等待某种资源的就绪,比如前面的scanf,比如一个进程要在硬盘中写入数据,因为硬盘的写入速度较慢,需要等待一段时间,那么这是进程就会进入阻塞状态,那么这时它的PCB就会被操作系统连入到硬盘提供的等待队列中。所以,状态的变迁实际上就是PCB被操作系统变迁到不同的队列中

下一个是挂起状态,它的前提是计算机资源已经吃紧了,这时操作系统会把内存中的一些无关紧要的代码和数据放到硬盘中,所以硬盘中有一个专门的分区用来辅助内存管理数据,叫Swap分区,Swap分区的大小也要适当,否则过度的使用Swap分区会产生负面影响,因为硬盘的访问速度比内存更慢。
什么叫无关紧要呢?比如处于阻塞状态的进程,它们白白的占着内存却不运行。所以这时就叫阻塞挂起。并且进程的PCB是不会放到Swap分区的,因为PCB是操作系统维护的一个数据结构,用来存放进程的相关信息,如果把这都放到了硬盘中,那操作系统就找不到这个进程了。
把数据和代码从内存拷贝到外设中我们叫唤出,从外设拷贝到内存中叫唤入

Linux中具体的状态

那么下面我们就来看一下Linux操作系统中的具体的进程状态,我们也可以在Linux中源码中看一看都有哪几种状态
在这里插入图片描述

running/sleeping状态

首先R就是running,运行状态我们已经解释过了,下面S是sleep睡眠状态,我们调用sleep函数时就是这种状态
在这里插入图片描述

这里的STAT这一列就表示状态,我们可以看到第一个进程就是处于S状态,而第二个进程就是我们的指令形成的进程,当我们查的时候它就要执行这个过滤加上色的指令,所以它就是运行状态。
我们加上sleep我们很好理解它处于sleep状态,当下面这样呢?

在这里插入图片描述
在这里插入图片描述
它竟然还是S状态,因为我们的printf是要等外设的,他是比较慢的,等外设时就只能是S状态。我们如果不打印,只有一个死循环,那它就是R状态
在这里插入图片描述
我们看到R后面还有一个+,那我们来解释一下。带着加号就表示前台进程,这时我们输入其他指令是不行的;不带加号就表示后台进程,这时是可以执行其他指令的。我们如果想让一个可执行程序后台运行,可以
在这里插入图片描述
这时我们就不能通过ctrl+c来关掉进程,我们可以通过kill命令来杀掉进程。

disk sleep状态

下面一个是D(disk sleep)状态,disk是磁盘的意思,磁盘睡眠顾名思义就是等待磁盘操作时处于睡眠的一种状态。跟我们前边说的阻塞的例子一样,所以其实S D状态都属于阻塞状态,因为它们都是在等待。
我们的S是可中断睡眠,我们可以中断sleep函数,但是D是不可中断睡眠,因为我们的IO请求如果中断,就会就会导致数据丢失或损坏,这可能对用户造成很大的影响,所以这种状态就相当于有一块免死金牌,内存严重不足时,操作系统也不会杀掉这种进程。(操作系统在没办法的时候是会杀掉某些进程的,如果不杀掉,操作系统就崩溃了,这是最严重的)

stopped状态

我们的kill命令实际上是给进程发送一些信号,比如-9就是kill信号,我们可以通过下面的指令来看一下
在这里插入图片描述
19是stop,18是continue,于是我们可以给进程发送stop信号,这时进程就处于stopped状态

在这里插入图片描述

tracing stop状态

当用gdb调试程序时,打一个断点,此时就处于tracing stop状态,就是跟踪停止状态,因为gdb在不断的跟踪运行代码
在这里插入图片描述
我们可以看到,它使用t表示的,其实T和t状态也是在等待,也属于阻塞的范畴

僵尸进程与孤儿

下面是两个表示终止的状态,Z是zombie,表示僵尸状态;X是dead,表示死亡状态。下面来说一下Z状态,僵尸就是一个尸体,此时进程已经死亡了,但是死了不就是dead吗?为什么要有僵尸呢?这是因为我们创建进程是想让进程去办事的,当进程结束时我们需要拿到进程的退出数据,它是正常退出还是异常退出?有没有完成我让它办的事呢?这些信息是需要父进程知道的。这些信息就存在PCB里边,所以,当一个进程处于僵尸时,它的代码和数据就已经可以释放了,但是PCB不可以释放,知道父进程拿到退出信息后才可以释放。我们知道了这些,那就可以来写一个代码来看一看这种状态。
在这里插入图片描述
我们写这样一个代码,前五秒子进程是正常的,后面父进程没有拿退出数据,此时子进程就是下面的僵尸进程,我们可以看到,最右边有一个defunct,意思是
在这里插入图片描述

在这里插入图片描述
其实所有进程推出前都要经历Z状态,因为每个子进程都要被它的父进程拿退出状态,如果父进程一直不读取呢?那僵尸状态就会一直存在,PCB对象就要一直存在,都是要占内存的,会造成内存泄漏只有在父进程退出或显式处理僵尸进程后,它才会被完全清除。
那如果是父进程比子进程先退出呢?那子进程就是孤儿进程,它会被一号进程领养,就是操作系统
在这里插入图片描述
我们也可以改一下上面的代码然后使用
在这里插入图片描述

我们可以看到,子进程的ppid变成了1,并且是在后台运行,X是一个瞬时的一个状态,我们不容易看到。

  • 18
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值