【Linux进程】进程状态(运行&&阻塞&&挂起)

 

目录

 

前言

 1. 进程状态

 2. 运行状态

 3. 阻塞状态

 4. 挂起状态

5. Linux中具体的状态

总结


前言

         在Linux操作系统中,进程状态非常重要,它可以帮助我们了解进程在系统中的运行情况,从而更好地管理和优化系统资源,在Linux系统中,进程可以处于不同的状态,本文我们来聊一聊运行、阻塞、挂起这几状态;

在这里插入图片描述

 1. 进程状态

         在许多教材以及资料当中有许多对进程状态的总结与描述,资料不同它们的描述也各有略同,但总都是一些概念,Linux进程状态具体是什么?本文我们将从底层出发,聊一聊运行、阻塞、挂起这几状态;

 温馨提示:如果在本文中某些名称或者内容不太了解,可以先阅读这篇文章:

Linux进程的理解

 2. 运行状态

       从计算机硬件出发,我们写的代码生成可执行文件都被存储在磁盘当中,想要让程序运行就必须将程序加载到内存当中;

        每一个程序(进程)都会有一个属于自己的PCB,通过PCB来进行排队,等待CPU的调度;

        为了便于调度管理,操作系统会在内存当中维护一个叫运行队列的结构,所有就绪状态的进程的PCB会被加入到这个队列当中;

        CPU在调度执行时就会通过这个运行队列拿到进程的PCB,进而调度执行该进程;

         只要进程在这个运行队列当中,它的状态就是运行状态;每个CPU在系统中都会维护一个运行队列;

 3. 阻塞状态

        了解完运行状态,我们再来聊一聊阻塞状态,阻塞状态是建立在进程被调度执行的基础上;

         在CPU执行一个进程时,都可能会或多或少的去访问系统的某些资源,比如:我们使用的scanf,在执行时需要调用键盘(本质就是从键盘中读取数据);

        我们不输入,键盘的数据就是没有就绪(进程需要访问的数据没有就绪),此时进程无法继续执行,需要等待数据;

状态又是如何转变的呢?

         操作系统和驱动程序它们对硬件进行管理,每个硬件都会有一个属于自己的结构描述,通过指针链接,操作系统通过链表(dev_list)达到对硬件设施的管理;

        当进程正在等待某个硬件的资源时,把进程的PCB加入到硬件设备结构描述的等待队列当中,并把PBC的状态设置为阻塞状态;当PCB在这个等待队列中等待数据资源时,这个状态就叫做阻塞状态;

         系统资源等待结束之后,操作系统会再次将等待队列中的PCB移入到运行队列当中,并把状态修改为运行状态,等待CPU的执行调度;

 4. 挂起状态

 了解完阻塞状态,我们来聊一聊挂起状态;挂起全称:阻塞挂起;

挂起是基于阻塞的一种状态;

        进程处于阻塞状态时,并且内存不足的情况下就会出现;

         针对于这种情况,操作系统会将阻塞进程的代码和数据置换到外设,此时该进程的状态就被称为挂起状态;

         阻塞进程的代码和数据一般会存放在磁盘的swap分区,当进程被操作系统调度时,被置换到外设的代码和数据又会重新加载到内存;

 拓展补充

         一般情况下,swap分区的大小不会太大,大概等于内存的大小,过大的swap分区会导致操作系统过于依赖swap分区,导致效率变低;

5. Linux中具体的状态

 说了这么多理论,那么在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 */
};

这是Linux内核源码对进程状态的定义;它其实并没有像阻塞挂起这样的状态;

我们也可以写一个程序来测试一下:

#include <stdio.h>
#include <unistd.h>

int main()
{
    while(1)
    { 
        printf("hello world! \n");
    }
    return 0;
}

在Linux环境下编译运行,然后使用监控进行观察:

while :; do ps ajx | head -1 && ps ajx | grep myprocess | grep -v grep; sleep 1; done
//myprocess是可执行文件的名称

 观察到的情况分为两种,大多数是S+,极少数是R+:

        主要是因为调用的printf,在输出时需要调用显示器,大多数的时间都是在等待显示器;我们也可以写一个空的死循环执行来观察;

R状态我们都知道是运行状态,S状态是什么?

         S(sleeping)休眠状态,这里的睡眠是浅度睡眠,可以对发送的信号做出响应;

 这里的 “+” 号是什么意思?

        进程被分为前台进程和后台进程,带+号就表示是前台进程;

  • 前台进程:正常使用 ./可执行程序,这种执行方式运行起来就是前台进程,前台进程运行时,无论我们怎么输入指令都无法被执行(Ctrl +c可终止进程)
  • 后台进程:./ 可执行程序 & 这种执行方式运行起来就是后台进程,后台进程运行时,我们输入的指令依然可以执行(Ctrl +c 无法终止进程,使用kill + 9 +进程pid 杀死进程)

 这里的S状态其实就是上述阻塞状态;

 D状态

         D(disk sleep)也是休眠状态,它是深度休眠,专门针对磁盘设计的;

 当进程需要将较大的数据写入到磁盘当中,在等待磁盘写入时进程的状态就是休眠状态;如果是S状态:

        在内存严重不足的情况下,操作系统没办法时会通过杀死进程的方式来节省资源;如果在等待的过程中进程被操作系统杀掉,并且磁盘写入数据失败,那么就会导致数据无法再加载(数据丢失);为了避免这种情况,就可以把等待数据写入的进程状态设为D状态;

D状态无法被杀掉(OS也不行),只能等待执行完毕后状态转换;

 注意:

如果用户看到了D状态,说明计算机几乎要挂掉了

 T状态

 T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行

kill -SIGSTOP  <进程ID>

 使用kill指令可以查看发送给信号的所有类型:

kill -l

 为什么要停止?

进程在访问资源时,可能暂时不允许进程访问,这时OS就会将进程的状态设置为stop(T状态)

 t状态

t状态也是停止状态,Linux中没有进行区分;

 主要出现在程序Debug时,在Debug的时候,遇到断点,进程就暂停,此时就是t状态

 在上述的D状态、T状态、t状态其实都是阻塞状态,阻塞可以等待硬件资源也可以等待软件资源

 比如:一个进程等待另一个进程,进程的PCB里可以有PCB* wait_queue,比如gdb的进程等待Debug的进程;

 X状态

        X状态(死亡状态),就是我们常说的终止状态,它是一个瞬时状态,不会在任务列表里看到这个状态
 

 最后就是Z(zombie)僵尸状态,僵尸状态较为复杂,Linux系统中的僵尸进程状态也是一种特殊的进程状态,通常是指一个子进程已经结束运行,但其父进程还未对其进行善后处理(如调用wait()函数)。如果不及时清理僵尸进程,会导致系统资源泄漏,影响系统性能甚至造成系统崩溃;

 


总结

         本文主要从底层出发向大家介绍了运行、阻塞、挂起这几种常见的状态,并且将Linux中具体的状态进行了一系列介绍,可以划分为这几种状态;最后是僵尸状态,僵尸状态的情况较为特殊,如果不及时处理也会造成比较严重的后果,我们下期再来进行详细的介绍,以上便是本文的全部内容,希望可以对你有所帮助,感谢阅读!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值