【linux进程】进程状态&僵尸进程&孤儿进程

一,linux下的特定进程状态

为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在Linux内核里,进程有时候也叫做任务):

R运行状态 (running)
S睡眠状态 (sleeping)
D磁盘休眠状态 (Disk sleep)
T/t停止状态 (stopped)
X死亡状态 (dead)

下面我们来对这几种状态进行介绍与理解:

1. R状态 vs S状态

我们先来看一段代码的对比:

代码1:
在这里插入图片描述
在这里插入图片描述

代码2:
在这里插入图片描述
在这里插入图片描述

我们不难发现:
休眠状态本质是进程什么都没做,但是明明打印了东西,为什么还是休眠状态呢,而没有打印语句的却是运行状态?

在这里插入图片描述

2. T状态 vs t 状态

T/t 进程让进程暂停,等待被进一步唤醒,那它们两者有什么区别呢?
在这之前,我们先来了解linux系统中信号

使用指令:kill -l 查看信号

在这里插入图片描述
红色框中是我们最近学习中会涉及的信号。

使用 kill -19 指定进程停止,可以发现进程的状态变成T:
在这里插入图片描述

接着使用kill -18 指定进程继续运行,进程状态有变成S休眠态:
在这里插入图片描述

但是当我们对这个可执行程序进行gdb调试时,再观察它的状态:
程序运行到断点处时,也会进入暂停状态,这种暂停状态为 t
在这里插入图片描述

结论:
T 是纯粹的暂停状态;
t 是进程被追踪是处在暂停状态(比如调试时)

3. D状态 vs S状态

细心的同学可能已经发现了,这几种状态中有两个很相似的状态:

S被称为浅度睡眠
D被称为深度睡眠

想象一下下面的这种情况:

我们从QQ,微信上下载一个文件,本质上就是将数据拷贝至磁盘,但是目前这个文件很大,需要拷贝很久,但是此时操作系统的内存恰恰不足了,需要干掉一些进程来保证操作系统存活,此时若恰好将正在拷贝到磁盘的进程杀掉了,那么也就是拷贝失败了,如果文件非常的重要,那么操作系统就要背锅了,所以OS创造了D状态:磁盘休眠状态!

结论:
1. S:浅度休眠,浅度睡眠,可以被终止
2. D:深度休眠,为了防止向磁盘写入重要资源时被杀掉而专门创建的一个分类!
在这里插入图片描述

二,OS中的进程状态

1. 运行状态

在这里插入图片描述
在这里插入图片描述

结论:
所以R状态可以这样理解:R状态不仅是进程在CPU上正在运行,而是进程已经准备好了(就绪),可以随便被调度了!

个进程一旦持有CPU,会一直运行到这个进程结束吗??

不会!!
因为现在的内核是基于时间片进行轮转调度的。个进程的时间片到了,就会从CPU上剥离下来,又被链到队尾。
(注:这种调度方式不是1inux操作系统内核的方式,是0S教材调度算法的一种)

让多个进程以切换的方式进行调度,在一个时间段内同时得以推进代码,就叫做并发

如果有两个CPU,就会维护两个运行队列,
一个进程在被一个CPU调度时,也可以同时
也被另一个CPU调度。任何时刻,都同时有多个进程在真的同时运行,我们叫做并行

2. 阻塞状态

问题:
1. 使用scanf时,如果不对键盘进行输入,此时进程处于什么状态? 为什么会处于这个状态? scanf在等待什么资源呢?
2. 0S要对所有硬件进行管理,如何管理?

下面我们来解决这几个问题:
1. 阻塞状态在linux系统中,对应的是S/D状态:
在这里插入图片描述

2.下图是OS对硬件和进程的管理示意图:
在这里插入图片描述

结论:
1.不是只有cpu才有运行队列哦,各种设备也有自己的wait queue!
而OS对硬件的管理形式,也类似于对进程的管理,也有对应的结构体,也使用链表的形式将其链在一起。
2.一旦把进程从运行队列中断链,放到设备的等待队列里,该进程就绝对不会被调度了。把这种状态的进程就叫做 阻塞进程!
3.阻塞和运行的状态变化,往往伴随着pcb被链入不同的队列中!
入队列的不是进程的什么代码和数据而是进程的task struct

3. 挂起状态

0S当前的内存很吃紧时,假设一个进程处于阻塞状态,意味着当前不会被调度了,0S就会该进程的代码和数唤出磁盘中的swap分区,原来那块空间就腾出来了:
在这里插入图片描述
1. 但是此时这个进程还是存在的,把这种状态叫做 挂起状态/阻塞挂起状态
如果设备已经等待就绪了,这个进程被挂到运行队列之前,会重新把代码和数据唤入回来
2. 挂起状态往往和其他状态组合,比如阻塞挂起,就绪挂起…
3. 挂起的主要目的就是解决内存的燃眉之急,更加合理的利用内存资源但是频繁的挂起会导致效率问题,所以挂起是以效率换空间的做法!

三,僵尸进程和孤儿进程

1. 僵尸状态和僵尸进程

1. linux中子进程在退出时,要把自己的退出信息保留在pcb结构体中,如果没有父进程读取这个进程的退出信息,那这个子进程就一直不释放,代码和数据会被释放掉,但是pcb结构体会一直存在。
2. 直到将来对子进程进行等待(wait),如果不等待,则这个子进程就会处于僵尸状态(Z状态),如果父进程读取了/等待了,这个子进程才会变成 X状态,进而 全部回收释放
3. 处于 Z状态 的进程也称为僵尸进程
4. 如果一直不回收释放,就会导致内存泄漏问题!!
5. 进程处于Z状态,无法被ki11掉,没有意义了。

代码演示:
在这里插入图片描述
在这里插入图片描述

2. 孤儿进程

1. 父进程先退出,子进程就称之为"孤儿进程"
2. 孤儿进程被1号init进程(OS)领养,当然要有init进程回收喽。

在这里插入图片描述
我们已经启动的所有的进程,我们怎么从来没有关心过僵尸呢?内存泄漏??

直接在命令行中启动的进程,它们的父进程是bash,bash会自动回收新进程的Z

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值