首页 >> 大全

一探Linux下的七大进程状态

2023-10-30 大全 30 作者:考证青年

本篇博客全站热榜最高排名:6

文章目录 三、Linux下的7种进程状态 4、停止状态T5、进程跟踪状态t6、死亡状态X7、僵死状态Z —— 两个特殊进程 四、总结与提炼

一、前言

Hello,大家好,本文我们所要介绍的是有关Linux下的进程状态

task_ 内容分类

二、操作系统学科下的进程状态

其实那么多的状态,真正主要的也就那么几个,所以接下去我会中重点讲解以下几种进程的状态

1、运行状态

首先我们要谈到的是【运行状态】,这个状态是最普遍的

因为每个进程是需要去竞争CPU资源的,但是呢CPU不可能同时给这么多进程分配资源

提问:一个进程只要把自己放到CPU上开始运行了,是不是一直要到执行完毕,才把自己放下来?

所以呢我们不要拿自己的时间感受去衡量CPU,其运行一遍速度是非常快的,你根本感受不到这种进程切换的效果

2、阻塞状态

在介绍完【运行状态】后,我们再来讲讲【阻塞状态】

上面的这两种状态都可以算作是进程处于阻塞状态

那有同学可能会疑惑这为什么叫做【等待队列】呢?明显只有一个进程鸭

3、挂起状态

最后我们再来讲讲一种状态叫做【挂起状态】

要怎么去省呢?

那有的同学说:为什么要这样去做呢?这样做有什么意义?

看了上面的三种基本的进程状态后我们可以来总结一下,如果要看进程是什么状态的话一般看这个 进程在哪里排队

三、Linux下的7种进程状态

在介绍完操作系统学科下的三种最主要进程状态后,我们对进程的状态有了基本的概念,接下去就让我们正式地来学习一下Linux系统下7种进程状态

先来小结并回顾一下上面所学:

如果当前是【运行状态】,那么接下来就需要被调度运行如果当前是【阻塞状态】,那就等条件就绪,等设备准备好就把当前进程投递到运行队列里,然后再被CPU调度运行如果当前是【挂起状态】,要做的就是把当时换出的代码和数据重新换入,然后再把所对应的进程列入到运行队列中

以下就是关于进程的所有状态

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 */
};

1、运行状态R

首先我们要来聊的是【运行状态R】

  1 #include <stdio.h>2 #include <unistd.h>3 4 int main(void)5 {6     while(1);                                                                7     {8         printf("hello bit\n");9     }10 11     return 0;12 }

  1 #include <stdio.h>2 #include <unistd.h>3 4 int main(void)5 {6     while(1);                                                                   7     //{8     //    printf("hello bit\n");9     //}10 11     return 0;12 }

那有读者就要问了:为什么把打印语句给去掉之后就变成这样了呢?

这里再补充说明一下这个S和R后面的+

不过呢,R状态并不代表这个进程就在运行,而代表其在运行队列中排队而已

2、浅度睡眠状态S

接下去我们再来介绍一下Linux下的睡眠状态S

  1 #include <stdio.h>2 #include <unistd.h>3 4 int main(void)5 {6     while(1)7     {8         sleep(1);                                                                   9         printf("hello bit\n");10     }11 12     return 0;13 }

那有同学就很疑惑,这个进程不是在运行吗?为什么不是R状态呢?

  1 #include <stdio.h>2 #include <unistd.h>3 4 int main(void)5 {6     int a = 0;7     printf("Enter# ");8     scanf("%d", &a);9 10     printf("echo : %d\n", a);11     return 0;                                                                         12 } 

3、深度睡眠状态D

除了【浅度睡眠】之外呢,还有一种叫做【深度睡眠】,它们俩呢,都是 阻塞状态

好,接下去呢我就通过一个故事来描述一下这个【深度睡眠】到底是怎样一种状态

所以呢,同学们,我们要明白这么一个道理:操作系统认为当前系统能行的话就直接让用户去用就可以了,如果扛不住了就置换页表,实在不行了就去会杀进程

一场有趣的官司

那因为随着这份重要数据的丢失呢,就引发了一场官司

以下呢,是三个人的辩词

【操作系统】:

法官‍⚖️听了这番说辞后心里想了想,确实是。于是呢这个时候便把茅头指向了丢掉数据的磁盘✒ 发问道:你为什么要丢数据呢?

【磁盘】:

操作系统一听:诶,这货说的好像确实没什么问题。那就就把视角转向了受害人即【进程】这一方。反正操作系统没错、磁盘没错,那就是你的问题喽!

【进程】:

那这个时候法官一想,它们三个说的似乎都挺有道理,难道是我错了吗?

那我们在上面有提到过处于【浅度睡眠】的进程,是可以被kill掉的,那么我们就要让这个进程的状态变为【深度睡眠】才对,即[D]

那这个时候就又有同学问了:D状态这么强大吗,那如果一个操作系统里有很多的D状态,这怎么办呢?

不过呢这个[D]就没办法在这里给读者演示了,因为D状态的进程只有处于高IO的情况才可以演示。有兴趣的可以去研究一下Linux下的命令dd

4、停止状态T

好,接下去呢我们来讲讲【停止状态T】

kill -l

kill -19 PID

kill -18 PID

所以呢,如果我们要将一个进程给终止的话,发送19号信号即可,要让其继续启动起来,则发起18号信号

那我现在要问了,这个T停止状态和S睡眠状态有什么不同呢?

状态进程 完全暂停了, 其不会再接收任何信号了一个进程通过状态可以控制另一个S和D一定是在等待某种资源,而T状态可能在等待某种资源,也可能被其他进程控制 5、进程跟踪状态t

接下去呢,我们再来说说进程的跟踪状态t,还记得我们在基础篇中所学习的 GDB调试 吗?

6、死亡状态X

对于【死亡状态X】来说呢,这个状态只是一个返回状态,你不会在任务列表里看到这个状态‍

第一种方法就是向这个进程发送9号信号,就可以杀掉这个进程

kill -9 PID

第二种方法就是通过这个进程的名称来杀掉它

killall 进程名

7、僵死状态Z —— 两个特殊进程

接下去我们来介绍一种状态叫做【僵死状态Z】,对于这个状态,我们要涉及到两个特殊的进程叫做 僵尸进程 与 孤儿进程

不过在讲这个僵死状态前,我们先来看看 0这个东西

这里我们写几句代码来测试一下

 36     int ret = 20;                                                                            37     if(ret == 20)   return 0;38     else    return 3;

① 僵尸进程

首先我们要来介绍的是僵尸进程,这里呢通过一个故事来进行引入

好,我们回归正题,来说说这个【僵尸进程】

那我现在想问了:有一个进程暂时退出了,它要将它的状态暂时维持一段时间,问题是它维持给谁看呢?

就上面这样生冷的文字来叙述还不太行,接下去我们通过实际的案例来观察一下

  1 #include <stdio.h>2 #include <stdlib.h>3 #include <unistd.h>4 5 int main(void)6 {7     pid_t id = fork();8     if(id == 0)9     {10         // child11         int cnt = 5;12         while(cnt)13         {14             printf("I am child, pid: %d, ppid: %d, cnt: %d\n", getpid(), getppid(), cnt);15             sleep(1);16 17             cnt--;18         }                                                                                                    19         exit(0);20     }21     else22     {23         // father   24         while(1)25         {26             printf("I am father, pid: %d, ppid: %d\n", getpid(), getppid());27             sleep(1);28         }29     }30     return 0;31 }

所以我们总结一下:

进程一般退出的时候,一般其不会立即彻底退出。如果父进程没有主动回收子进程信息,子进程会一直让自己处于Z状态,这也是为了方便后续父进程读取子进程的相关退出结果。

那对于上面的这种子进程,我们就将其称作为是【僵尸进程】,不过呢这种进程是存在一定危害的!

② 孤儿进程

那此时我想问:这个父进程突然之间退出了,但是呢它的父进程并不知晓,那为何这个父进程没有处于【僵尸状态Z】呢?

接下去我们来将上面测试僵尸进程的代码做个修改,让父进程先于子进程退出

  1 #include <stdio.h>2 #include <stdlib.h>3 #include <unistd.h>4 5 int main(void)6 {7     pid_t id = fork();8     if(id == 0)9     {10         // child11         int cnt = 500;12         while(cnt)13         {14             printf("I am child, pid: %d, ppid: %d, cnt: %d\n", getpid(), getppid(), cnt);15             sleep(1);16 17             cnt--;18         }19         exit(0);20     }21     else22     {23         int cnt = 5;24         // father   25         while(cnt--)                                                                                26         {27             printf("I am father, pid: %d, ppid: %d\n", getpid(), getppid());28             sleep(1);29         }30     }31     return 0;32 }

ps ajx | head -1 && ps ajx | grep systemd

那为何会出现上面这种现象呢?是这个子进程突然换父进程了吗?

但是这个孤儿进程为什么要被领养呢?

那其实我们就可以解释上面的事情了

四、总结与提炼

最后来总结一下本文所学习的内容

接下去我们又介绍了在Linux系统下的七种进程状态,分别是:运行状态R、浅度睡眠状态S、深度睡眠状态D、停止状态T、进程跟踪状态t、死亡状态X、僵死状态Z

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了