进程(2)——进程状态(僵尸,睡眠……)【linux】

进程(2)——进程状态(僵尸,睡眠……)【linux】

  • 一.操作系统的进程状态:
    • 1.1 运行态
    • 1.2 阻塞态
    • 1.3 挂起态
  • 二.linux进程状态
    • 2.1 R——运行状态
    • 2.2 S——浅度睡眠状态
    • 2.3 D——(disk sleep)深度睡眠
    • 2.4 t/T(stop)
    • 2.5 X:(dead)
    • 2.5 Z:(zombie)
  • 三.孤儿进程:

一.操作系统的进程状态:

我们知道进程有多个
假设现在只有一个一个CPU,那进程会去争抢cpu的资源。
这个时候cpu会有一个运行队列,来实现让进程按照顺序执行。
进程(2)——进程状态(僵尸,睡眠……)【linux】_第1张图片

这个是进程的运行队列,一个个进程都加载进运行队列中。

这个时候对应进程的代码和数据都加载进了进程之中

所以说内存不光要维护PCB,同时还管理着程序的代码和数据。

1.1 运行态

在运行队列中的进程就是运行态

1.2 阻塞态

因为进程未被内存读取前是在磁盘中的程序,所以对进程的管理实际上是操作系统对软件的管理

如果进程需要访问硬件(设备)中的资源,这个时候就要涉及到操作系统对进程的管理。

操作系统管理硬件也是先描述再组织,对硬件也会进行描述,硬件中有等待队列。
每个设备都有个等待队列
比如说一个进程需要键盘进行输入,操作系统就会让该进程进入到该设备等待队列
在设备的等待队列中的进程就叫阻塞态

比如说C语言的scanf函数等待输入时,这个时候就是阻塞状态

1.3 挂起态

我们要注意,当进程处于阻塞态中
进程的自身代码和数据还是存在内存中。

如果这时候进程在阻塞态中等待设备资源就位时
突然操作系统内部的内存资源不足了。

操作系统就会在进程中进行检查
将一些在挂起态的进程的pcb保留,将内存中的代码和数据从内存中丢弃

当进程所需的设备资源就位时,再将数据和代码从磁盘中重新读取

二.linux进程状态

上面的操作系统中的进程状态我们只是随便提一下而已。

我们的学习重心还是要放在Linux系统的进程状态上来。
进程(2)——进程状态(僵尸,睡眠……)【linux】_第2张图片

2.1 R——运行状态

这里我们那test.c进程测试一下
进程(2)——进程状态(僵尸,睡眠……)【linux】_第3张图片

这里用grep进行测试。
进程(2)——进程状态(僵尸,睡眠……)【linux】_第4张图片
这里我们能发现test处于R+的运行状态。

这里的+先不谈,之后的博客中会进行讲解。

2.2 S——浅度睡眠状态

这里的S的睡眠状态,可以看成是操作系统中的阻塞状态。

这这里我们同样可以进行测试一下:
进程(2)——进程状态(僵尸,睡眠……)【linux】_第5张图片

在这里插入图片描述
这里我们能发现进程一直处于设备资源的到位,处于S的阻塞状态。

2.3 D——(disk sleep)深度睡眠

前面我们在操作系统进程的挂起态中我们提到:
当内存太满的时候,系统有可能,会自己干掉进程

但是如果遇到一个进程正在向磁盘写入数据,正好被干掉的话,就会导致数据的丢失。
如果正好是比较重要的数据,那这个后果是不能承受的

所以创建了一个深度睡眠模式
专门交给那些向磁盘写入数据的进程。
防止系统误杀进程,从而造成数据丢失。

2.4 t/T(stop)

这个状态可以看作是程序处于设备等待队列的阻塞状态。

只不过这个阻塞状态不光是系统控制的,我们用户可以进行停止和继续。

这里就比如说gbd调试
我们打了断点后进程运行到断点处,就会进入stop状态

进程(2)——进程状态(僵尸,睡眠……)【linux】_第6张图片
这里我们在程序的第四行打一个断点,然后运行程序。

进程(2)——进程状态(僵尸,睡眠……)【linux】_第7张图片
就会发现这里的进程处于:
gdb test会等待指令进行下一步的阻塞态
而test处于t状态

2.5 X:(dead)

终止状态 :在相关进程丢尽垃圾队列中等待释放。

2.5 Z:(zombie)

当子进程死了以后,不会立马进行释放,而是会保留子进程的PCB以及内存和资源,让关心子进程的进程或者父进程来检查
确定了子进程的结束原因以后,之后再在放入终止状态。
这个保留PCB和内存资源的状态,就叫僵尸状态
这里可以来测试一下
进程(2)——进程状态(僵尸,睡眠……)【linux】_第8张图片
这里我们用fork函数,让子进程消失,让父进程保留。

进程(2)——进程状态(僵尸,睡眠……)【linux】_第9张图片
这里我们会发现这里的子进程处于Z状态

所以如果僵尸进程处理不当就会引起内存泄漏
进程一般退出的时候,如果父进程没有主动回收子进程的信息。
子进程会一直让自己处于Z状态,进程相关资源尤其是task_struct不会被释放。
僵尸进程会一直占用内存资源(内存泄漏)。

就比如我们上面的测试代码,这个时候子程序会一直处于僵尸状态

至于如何处理,这个就留到之后的博客了

三.孤儿进程:

父子进程,父进程先退出,子进程的父进程会被改成1号进程(操作系统),相当于被系统给领养
这里可以来测试一下:

这里我们让父进程先走,然后不停打印子进程的父进程pid
进程(2)——进程状态(僵尸,睡眠……)【linux】_第10张图片
这里我们就能发现父进程从3090变成了1
进程(2)——进程状态(僵尸,睡眠……)【linux】_第11张图片
这里就看出子进程被操作系统给收养了。

为什么要领养:
因为子系统进入Z状态的话,这样就没有人来收尸了。

你可能感兴趣的:(linux)