【Linux进程三】进程的状态
【Linux进程三】进程的状态
- 一.操作系统的进程状态
- 1.运行状态
- 2.阻塞状态
- 3.挂起状态
- 二.Linux的进程状态
- 1.前台进程和后台进程
- 2.休眠状态和磁盘休眠状态
一.操作系统的进程状态
操作系统管理的是进程的PCB块,那么很显然,进程状态就是PCB中的一个变量,可以使用宏定义来实现
#define NEW 1
#define RUNNING 2
#define BLOCK 3
struct PCB
{
// ...其他配置
int state; // 进程状态
}
if(PCB->state==NEW)
{
//将进程放入运行队列
}
else if(PCB->state==BLOCK)
{
//将进程放入阻塞队列
}
Linux中常见的六种状态:
还有一种叫做僵尸状态
1.运行状态
- CPU有8核、16核,相当于CPU可以同时处理多少任务
- 相当于有很多小CPU 每个小CPU都有自己的运行队列,CPU会从中寻找数据来处理
- 只要一个进程在运行队列中,无论是否在被处理,都属于运行状态
2.阻塞状态
当CPU处理一个进程时,或多或少都会访问些外部设备,比如磁盘、网卡等
举例:当代码运行到scanf和cin时,系统等待用户输入,只要用户不输入,那么要访问的资源就没有就绪,代码无法继续与运行,这就是阻塞状态吗?对,但不全对
系统中的硬件是通过被管理硬件数据来间接被操作系统管理的,因此操作系统很清楚每个硬件是否具备访问条件,为什么?
因为每个设备的结构体中都有一个变量叫:PCB* wait_queue,称为等待队列
将一个进程从运行队列移动到等待队列后,再将状态改为阻塞状态,这时进程才处于阻塞状态
进程变化的本质是:
- 更改PCB中的status整数变量
- 将PCB链接到不同的队列中
3.挂起状态
当很多进程被阻塞,同时操作系统的内存资源已经严重不足
操作系统会将这些PCB对应的数据和代码移动到磁盘的swap分区,为内存提供空间
这些被移动到磁盘的PCB就处于挂起状态
将内存中的数据移动到外设上的操作是针对所有阻塞进程的
虽然与外设频繁的交互会影响操作系统的效率,但危急时刻操作系统首先要活下去
swap分区在磁盘中空间很小,是专门用于缓解内存不足的情况,当危机解除后,这些被移动到磁盘的代码和数据会返回内存
二.Linux的进程状态
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
我们用一段代码观察一下进程:
可以看到该程序的状态
按理讲,一个正在运行的程序应该处于R状态,但这个程序却处于S状态
这是因为IO输出很慢,打印字符时会和屏幕交互,因此大部分时间处于阻塞状态,只有极短时间是出于打印状态
如果这个程序什么也不打印,就会一直处于R状态
1.前台进程和后台进程
- 前台进程:运行时无法使用bash外壳的指令,且可以被Ctrl+C终止
- 后台进程:运行时可输入指令,不能被Ctrl+C终止,只能使用kill指令杀掉
将程序变为后台程序:(运行时加上&)
如:./mybin &
2.休眠状态和磁盘休眠状态
- S(sleeping):浅度休眠,浅度睡眠,可以被终止
- D(disk sleep):深度休眠,为了防止向磁盘写入重要资源时被杀掉而专门创建的一个分类
应用情况:
当我们在互联网上下载资源时(将数据拷贝到磁盘),会遇到文件很大下载时间很长的情况,如果在下载时内存不足,操作系统就会杀掉一些进程保证自身存活,若恰巧将正在拷贝下载数据的进程杀掉,拷贝就会失效,因此才需要D状态