进程的状态

前言

今天我们要学习进程PCB中特别重要的一个字段,其实就是一个变量,比如int state,它来标识进程当前处于什么状态。

它可能是定义宏的方式,或者枚举的方式实现的等等,具体要看操作系统是什么。

#define NEW 1
#define RUNNING 2
#define BLOCK 3
struct PCB
{
    int state//状态
    //其他属性
}
if(PCB->state==NEW)
{
    //将该PCB放入运行队列之中
}
else if(PCB->state==BLOCK)
{
    //将该PCB放入阻塞队列之中
}
…………

所谓的状态变化就是变量的变化。

下面我们说的三个进程状态是以统一的视角来看待操作系统的。

一.OS中的运行状态

一般而言,我们的电脑都是单cpu的,几个cpu会维护几个运行队列

image-20240708205929869

只要进程的pcb连接到运行队列之中,就说明该进程已经是准备好了,可以随时被调度。

二.OS中的阻塞状态

我们的代码中或多或少是会访问系统中的某些资源,比如:磁盘,键盘,网卡等各种硬件设备。

#include<stdio.h>                                                                    
int main()
{         
    int num=0;
    printf("请你输入一个数\n");
    scanf("%d",&num);
    printf("num=%d\n",num);
    return 0;            
 }

image-20240708213201003

scanf本质上是我们想从键盘中读取数据,现在我就是不输入!键盘中的数据就是没有就绪,进程想访问的资源就没有就绪,进程后续的代码就无法往后执行。

现在是阻塞状态了吗?是的。已经处于阻塞状态了,下面是具体的原因。

操作系统需不需要知道该设备的状态变化呢?答案是一定需要知道,而且是最先知道的。

image-20240708214213048

之前我们就说了,操作系统需要将硬件设备给管理起来,使用六字箴言-先描述,再组织

在硬件设备的的pcb中有个字段PCB*wait_queue

image-20240708221248110

之前就说过了,操作系统中存在很多队列,运行队列,等待队列,设备的等待队列等。

此时的进程被链接到了设备的等待队列中去了,状态被改成了阻塞状态。

此时的进程就变成的阻塞状态了。

这里我们就得出了一个结论:

进程状态变化的本质:

**1.**进程的state发生变化。

**2.**将进程的pcb链入不同的队列中。

上面我们说的过程都是跟进程的pcb相关,跟代码和数据没有关系。

当进程的pcb由运行队列到等待队列时,就叫被阻塞了。

当进程的pcb由等待队列到运行队列时,就叫被唤醒了。

三.OS中的挂起状态

当一个进程现在处于阻塞状态,说明它的资源没有准备就绪,os就无法调度该进程,那恰好此时os中的内存空间已经严重不足了。这时该怎么办呢?

磁盘中有个分区,叫swap分区,这是专门针对物理内存严重不足的时候使用的,负责将内存中pcb的代码和数据拷贝到swap分区之中。磁盘嘛,属于外设了,速度比较慢,这里不用担心速度慢,这是必然的,因为现在担心的是os是否能够正常的执行下去。

一个关乎生死,一个关乎生活质量,肯定生死为第一要务啊!

其中这个swap分区的大小是和内存中的大小相关联的:

物理内存小于2GB,swap分区大小为物理内存大小的两倍。
物理内存大于2GB,swap分区大小为物理内存大小+2GB。

image-20240709104404585

此时该pcb的代码和数据被交换到硬盘中后,该进程就叫做阻塞挂起了。

当物理内存缓过来之后,os需要重新调用该进程,那么就将该进程的代码和数据加载到内存中来。

这些操作全部由操作系统一个人完成。

四.linux进程中的各个状态

接下来我们来看看linux进程下特定的一些进程状态。

a744c9888358072c62f2a8573929b8ae

这里我们倒是看到了运行状态,但是为什么没有阻塞,挂起状态呢?难道上面我们说错了?显然不是。上面说的操作系统是站在统一的视角来看待所有的操作系统的,具体是什么阻塞,什么挂起,要看具体的操作系统。

1、R(running)运行状态

定义:进程要么在运行中,要么在运行队列之中。

看一段代码:

#include<stdio.h>
#include<unistd.h>
int main()
{
    while(1)
    {
       printf("这是一个进程\n");
       sleep(1);
    }
    return 0;
}

监控脚本while :; do ps ajx | head -1 && ps ajx | grep mycode | grep -v grep;sleep 1; echo “##################” ; done

image-20240709135605958

在监控中我们可以看到有进程的pid和ppid,其中还有一个STAT字段,这就是进程的状态。

该进程使用while循环,一直在运行,一直在打印,这里的状态不应该是R,运行状态吗?为什么这里是S+状态呢,S叫浅度睡眠。+(待会细说)。

我们知道硬件设备的处理速度是比较慢的,而cpu的处理速度是非常快的,这里一直使用printf在屏幕上打印,它的速度比起cpu的速度慢太多了,printf打印的时候,大部分都不是就绪的,它是阻塞的,也就是该进程其实不是一直在运行队列的,它是在运行队列和阻塞队列反复跳转。

如果我们运气比较好,这个监控脚本观察这个进程的状态,可能是会出现S+状态的。


当我们将printf函数取消后,只写while循环,这时该进程就一直在cpu的运行队列上运行。

这时这里的状态就变成了S+。

image-20240709141439361

image-20240709141422116

2、前台进程和后台进程

在操作系统中,进程可以分成前台进程和后台进程。

比如在windows中前台进程有文本编辑器,关闭窗口后,用户就无法使用了。

后台进程有QQ音乐,将窗口关闭后,音乐还是可以一直播放。

在linux中进程的状态带+的是前台进程,不带的是后台进程。

正常我们使用gcc/g++编译文件得到的可执行程序,使用./可执行程序命令运行,此时的进程都是前台进程,在该进程运行起来的时候,我们输入各种命令是不起作用的。

image-20240709142646536

当我们./可执行程序后面加上符号&,此时的进程就变成了后台进程。

比如:./mycode &

变成后台进程后,我们输入各种命令也是会起作用的。

image-20240709152416839

就算是你的命令符号是隔开输入的,只要按下回车,该命令依然是会作用。

后台进程使用命令ctrl+c是没办法终止的,因为ctrl+c是给前台进程发送2号信号SIGINT使得前台进程终止的。

对于后台进程是不起作用的。

使用命令:pgrep+mycode。查看进程的pid。

然后使用命令【kill -9 该进程的pid】来杀死后台进程。

3、S(sleeping)浅度睡眠状态

进程的浅度睡眠状态是一种“广义上”的阻塞状态,也叫可中断睡眠,它会对外部信号做出回应。

可以使用kill信号给杀死或者被唤醒。

4、D(disk sleep) 深度睡眠状态

深度睡眠,是针对于磁盘的,也叫磁盘睡眠状态。它是一种不可中断睡眠。

当进程的关键数据正在写入磁盘中时,此时的进程就处于深度睡眠状态。

操作系统都没资格来杀死该进程。

5、T(stopped)终止状态(阻塞状态)

image-20240709155056472

19号信号就是停止进程的,我们还可以使用18号信号来唤醒进程。

注意:此时的进程从前台进程变成了后台进程。

image-20240709155415011

6、t(tracing stop) 追踪停止状态

t状态是针对gdb调试debug程序的时候出现的状态。

使用命令n,进程就运行一下,遇到下一个断点,就停止。

在gcc编译文件后面加上-g,即加上调试信息。

image-20240709160610206

image-20240709161317238

打了断点后,使用r运行,此时进程就停止在了断点处,此时的进程状态就变成了t状态。

但是现在,T状态和t状态几乎是不分家的,都是停止状态。

7、X(dead)死亡状态

比如使用kill -9杀死的进程,状态就是死亡状态。

8、Z(zombie)僵尸状态

僵尸进程:当子进程退出时,父进程没有对其进行回收处理。

僵尸进程的状态就叫做僵尸状态(下一节细说)

  • 22
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值