当前位置: 首页 > news >正文

[Linux系统编程——Lesson4.进程状态]

目录

前言

一、什么是进程状态?

三、操作系统(OS)下的 --- 进程状态

💧运行状态💧

 💧阻塞状态💧

💧挂起状态💧

四、Linux下的7种进程状态

🔥运行状态 -- R🔥

 🔥浅度睡眠状态 -- S🔥

 🔥深度睡眠状态 -- D🔥

🔥停止状态 -- T🔥

🔥进程跟踪状态 -- t🔥

🔥死亡状态 -- X 🔥

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

① 僵尸进程

 ② 孤儿进程

 五、总结

六、结束语


前言

         进程 只有被 操作系统(OS)管理好了,才能发挥它的全部作用,而 系统 中存在多个 进程操作系统(OS)无法做到面面俱到,因此为了更好的管理 进程,操作系统把 进程 分成了几种状态:运行、阻塞、挂起、休眠等等。至于每种状态的应用场景是什么?有什么用?本文将会带大家认识各种 进程 状态

在谈 进程状态 之前,我们需要了解 什么是进程、怎么去描述并组织进程、如何创建一个进程

  • 操作系统(OS)的本质是:先描述,在组织
  • 操作系统并非直接管理 -- 进程,而是管理 进程 的 PCB(task_struct)
  • PCB 中有着进程的各种信息,包括:PID、PPID 、进程状态
  • 我们可以通过函数 getpid()  获取当前进程的  PID
  • 进程 间存在父子关系,可以通过 fork() 主动创建 子进程
  • 父子进程 相互独立,共享一份代码时,具有 写时拷贝 机制
  • 如果大家还有不了解-- 进程 --的可以先看一下这篇文章:[Linux系统编程——Lesson3.进程概念 ]
     

一、什么是进程状态?

为了弄明白正在运行的进程是什么意思,我们需要知道------进程的不同状态

  • 本质定义:进程状态本质上是进程控制块(PCB,在 Linux 中为 task_struct 结构体)内部的一个整型变量(int status),它仅作为标志位标识进程当前的状态。

  • 状态变更机制:操作系统改变进程状态时,核心操作是修改 PCB 中该状态变量的值,通过更新这个标志位来体现进程状态的转变。

  • 实际应用(以 Linux 为例):

    • task_struct 中的 volatile long state 字段用于记录进程状态
    • 不同数值代表不同状态(如 - 1 表示不可运行,0 表示就绪可运行,>0 表示已停止等)
    • 状态变更常伴随 PCB 在不同队列间的移动(如从运行队列到等待队列)
  • 核心意义:状态标志位是操作系统对进程进行调度和管理的基础依据,通过它可以高效跟踪和控制系统中所有进程的运行情况。

简言之,进程状态就是 PCB 中的一个状态标志,操作系统通过修改这个标志来实现对进程状态的管理,这是进程调度机制的基础。


那么 状态 决定了什么呢❓

  • 进程后续的动作! ---- 而 操作系统(OS)中可能会存在多个进程都要根据它的状态执行后续动作所以说明 --状态-- 对于  操作系统后续如何管理 进程十分重要!!

二、操作系统(OS)下的 --- 进程状态

  • 对于进程而言呢,它是操作系统中的概念,如果有学习过《操作系统》这门学科的话应该可以很清楚对于进程而言的话是存在着许许多多的状态,如果一开始刚刚接触的小伙伴一定会感觉这么多状态要怎么区分呀😵

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

💧运行状态💧

首先我们要谈到的是【运行状态】,这个状态是最普遍的:  进程 PCB 被调度到 CPU 运行队列中且已被分配 CPU 资源,就叫做 ------ 运行状态

一个CPU,一个运行队列也就是说这些进程都需要在CPU这里进行排队,逐个执行。

而排队的是进程么❓

其实不是,排队的是进程的PCB(面试时不是你在排队,而是你的简历信息在排队)。


  • 首先对于一个进程而言,我们知道它是由 内核数据结构 + 所对应的代码和数据 所组成的,所以当系统中存在多个进程的时候就势必会存在多个结构体;当然我们需要将这些进程给链接组织起来(双向链表链接)
  • 那么这些 进程 就相当于是在处在一个运行队列中,我们如果要找到这个队列中的某个进程的话,只需要找到这个进程的头部即可,那我们就可以对应地去调度某个进程,把这个进程所对应的代码和数据放到CPU上去执行


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

  • 所以每一个CPU都会去维护一个运行队列,里面的队 头指针 head 所指向就是第一个进程所对应的【PCB】队尾指针tail 所指向就是最后一个所对应的【PCB】。所以我们要运行某一个进程只需要将 head 所指向的那个进程放到 CPU上去运行即可

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

  • 不是,每一个进程都有一个叫做:时间片的概念! 其时间大概是在10 ms左右。所以并不是一个进程一直在执行,而是这多个进程在一个时间段内所有代码都会被执行 —— 这就叫做【并发执行】 
  • 所以呢这就一定会存在大量的进程 被CPU放上去、拿下来的动作 —— 这就叫做【进程切换】 

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

     💧阻塞状态💧

     何为阻塞

    • 阻塞 就是 进程 因等待某种条件就绪,而导致的一种不推进状态(比如等待 键盘输入)。
    • 通俗的来说 阻塞 就是 进程卡住了,原因就是缺少资源

    比如在我们日常生活中,常常发生堵车,原因就是道路资源不够用了,车辆这个 进程 就需要原地等待 

    那么进程需要什么资源呢?

    • 比如 磁盘网卡显卡 等各种外设
    • 假设你现在想在 steam 上下载游戏,当你点击下载按钮后提示磁盘空间不足,此时是无法运行 steam下载 这个进程的,因为此 进程 需要等待足够大的 磁盘资源
    • 此时我们就称此 进程 为 阻塞 状态

     总结: 进程 阻塞 就是不被调度

    • 此时 PCB(task_struct) 就会被设置为 阻塞状态,并链入等待的资源提供的等待队列
    • 没错,这里的等待队列 类似于 CPU 运行队列 

    💧挂起状态💧

    挂起(阻塞挂起):

    • 当 CPU 资源紧张时,将 进程的数据和代码 交换至 磁盘 中挂起,此时内存中只有 PCB
       
    • 挂起 可以看作一种特殊的 -- 阻塞状态

    详解:

    • 当计算机资源比较吃紧时,操作系统一定要确保自身不会因为资源的紧张而崩溃,所以就会将一些等待资源(阻塞)的进程的代码和数据交换到磁盘的 swap分区 中,这个过程称为唤出。
    • 当需要调度此进程时,就会将磁盘的 swap分区 中保存的内容换回到内存中,这个过程称为唤入。

    注意:交换的是进程的代码和数据,不是PCB!!如果PCB被交换出内存了,那操作系统如何管理呢?

    所以当某个进程的代码和数据不在内存中,而被换出到磁盘上时,该进程就为挂起状态。


    思考:swap分区是越大越好么? 

    • 磁盘本质是输入输出设备,每次唤入唤出其实都是非常低效的操作,如果swap分区设置的过大,那么操作系统就会十分依赖它,导致出现更多低效IO,这本身就是一种牺牲效率来确保操作系统能够正常运行的行为。
    • 所以swap分区不宜设置的过大,一般为内存大小或内存大小的一半,具体要看不同的操作系统。

    举个-- 挂起-- 例子 : 

    在我们生活中,一边走路一边玩手机很危险,所以此时我们会将玩手机这个 进程挂起 ,即把手机揣进兜里,然后 专心执行走路这个 进程

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

    • 位于【运行队列】的话它就是处于运行状态
    • 位于【阻塞队列】的话它就是处于阻塞状态

    三、Linux下的7种进程状态

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

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

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

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

    🗝️运行状态 -- R🗝️

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

    • 来看下下面的这段代码,是一个死循环去 printf打印循环语句
       #include <stdio.h>#include <unistd.h>int main(void){while(1);                                                                {printf("Hello process, pid: %d\n",getpid());sleep(1);}return 0;}
    • 然后我们将下面的代码给运行起来,观察这个进程的状态时,看到其显示为 S+,不过呢读者想看到的应该是 R 才对

    • 接下去呢,我们把代码修改一下再来看看,不使用 printf打印语句了,而且直接使用一个while(1)去做循环
       #include <stdio.h>#include <unistd.h>int main(void){while(1);                                                                {//printf("Hello process, pid: %d\n",getpid());//sleep(1);}return 0;}
    • 然后我们看到,此时再运行起来时这个进程的状态就改变了,变成了 R+,这才是我们想要的【进程状态】

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

    • 原因就在于 printf 打印语句它是属于 IO流 的一种,第一次因为是循环的缘故,它一直在等IO设备就绪,所以其进程状态就一直为 S+,对应的即是在操作系统中的【阻塞状态】;但是当我们去掉 printf 这种IO流之后呢,它就是在纯纯运行,没有IO,那也就变成了 R 状态

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

    • 这里的 R+ 代表的就是这个进程是在前台运行的,所以我们在输入任何指令后不会对其造成 任何的影响

    • 那若是我们不以正常的方式去启动这个进程的话,其进程的状态就会不一样了,可以看到我在 ./mytest 的后面加上了一个 &;那么其状态变成了 R,此代表的意思就是这个进程它是运行在了【后台】的

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

    总结:
              "+"代表是前台运行,无"+"代表后台运行,后台运行时可在命令行继续输入指令并执行,但无法用ctrl+c结束,需要用kill -9 pid杀死。想要后台运行某个程序就在后面加"&",如:./test &

     🗝️浅度睡眠状态 -- S🗝️

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

    • 我们再通过一段代码来看看
       #include <stdio.h>#include <unistd.h>int main(void){int a = 0;printf("Enter# ");scanf("%d", &a);printf("echo : %d\n", a);return 0;                                                                         } 
    • 将该进程运行起来我们可以看到其是出于 S+ 的状态,因为【shell】此时正在等待用户的输入,这个就对应到了我们上面所讲到的 阻塞状态

     🗝️深度睡眠状态 -- D🗝️

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

    • 对于浅度睡眠来说,之所以称为 “浅度”,是有原因的:也就是处于这种状态的进程容易被唤醒。例如说我们在上面所讲到的这个处于阻塞状态的进程,我们使用 kill -9 PID 向这个进程发送【9号信号】,那么这个进程就被杀死了,你也可以认为被唤醒了

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


    🧐小程的 “深度睡眠” 历险记:一个进程的休眠故事

    • 小程是电脑世界里一个普通的 “文档保存进程”,他的工作很简单 —— 每当用户点击 “保存” 按钮时,就把文档里的文字、图片打包,送到硬盘仓库里存好。
    • 这天下午,用户写完报告后点了 “保存”,小程立刻忙碌起来:他先从内存暂存区接过文档数据,又跟硬盘仓库的管理员核对存储地址,忙了半分钟,终于把数据稳稳当当地存进了硬盘的 “F 盘文件夹货架”。
    • “任务完成!” 小程擦了擦额头的汗,刚想歇口气,却听见操作系统 “大管家” 的声音:“小程,接下来暂时没你的活了,先去‘深度休眠区’歇着吧,等用户下次点‘保存’,我再叫你。”
    • 小程有点疑惑:“为啥不能在工作区等着呀?我随时能干活的!”
    • 大管家笑着解释:“你看工作区里,‘键盘输入进程’正等着用户打字,‘屏幕显示进程’要实时更新内容,大家都忙着呢。你现在没任务,要是占着工作区,不仅会让工作区挤挤巴巴,还会浪费 CPU 的‘注意力’——CPU 每隔一会儿就会问‘谁要干活’,你总说‘我没有’,不是白忙活吗?”
    • 说着,大管家带小程来到一个安静的 “深度休眠区”。这里躺着不少进程:有 “自动备份进程”(要等凌晨 3 点才工作),有 “压缩文件进程”(用户还没选要压缩的文件),大家都安安静静地坐着,不像工作区里那么热闹。
    • “来,把你的‘身份卡’(PCB)给我改一下。” 大管家接过小程的身份卡,在 “状态” 那栏的数字上划了一下 —— 原来写着 “0(就绪)” 的地方,改成了 “2(深度休眠)”。“你看,现在你的状态变了,CPU 下次点名时,看到这个数字,就知道不用叫你了;等用户下次点‘保存’,我再把这个数字改回来,把你送回工作区。”
    • 小程点点头,找了个空位坐下。他发现自己一进入深度休眠状态,就像被按下了 “暂停键”—— 不用再留意 CPU 的点名,不用惦记有没有新任务,整个人都放松下来。他旁边的 “自动备份进程” 打了个哈欠:“别担心,这里特别安稳,除非有‘唤醒信号’(比如用户触发任务、到达指定时间),否则咱们能一直歇到该干活的时候。”
    • 就这样,小程在深度休眠区里安安静静地待着。直到傍晚,用户又打开文档改了几行字,点击 “保存” 的瞬间,大管家立刻找到小程的身份卡,把 “状态” 改回 “0(就绪)”,然后拍了拍他的肩膀:“该干活啦,回工作区吧!”
    • 小程伸了个懒腰,跟着大管家回到工作区 ——CPU 刚好点名,看到他的状态是 “就绪”,立刻把 “注意力” 分给了他。小程熟练地接过新的文档数据,又开始了熟悉的工作。
    • 后来小程才明白,“深度睡眠”(深度休眠状态)根本不是 “偷懒”,而是电脑世界的 “智慧安排”:通过给暂时没任务的进程改个 “状态数字”,让它们暂时退出工作区,既节省了资源,又能让需要干活的进程更高效 —— 而那张小小的身份卡(PCB)上的状态数字,就是决定他 “该休息” 还是 “该干活” 的关键标志。

    • 深度睡眠状态/不可中断睡眠状态/磁盘休眠状态,顾名思义,在这个状态的进程不会被杀掉,哪怕是操作系统也不行,通常会等待IO的结束。
    • 例如,某一进程要求对磁盘进行写入操作,那么在磁盘进行写入期间,该进程就处于深度睡眠状态,是不会被杀掉的,因为该进程需要等待磁盘的回复(是否写入成功)以做出相应的应答。
    • 如果在这个过程中,操作系统能够杀死该进程,那么就有可能丢失数据。
       

    🗝️停止状态 -- T🗝️

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

    • 首先我们要通过下面这句命令来查看一下对应的进程信号
    kill -l
    
    • 此处我们要使用到的是18、19号信号

    • 接下去我们就来试一试如何让这个进程暂停之后又重新启动会是怎样的
    #include <stdio.h>
    #include <unistd.h>int main()
    {while(1){printf("hello my process: %d\n",getpid());sleep(1);                                                                                       }return 0;}

     所以我们来总结一下

    • 暂停进程
    kill -19 PID
    
    • 启动进程
    kill -18 PID
    

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


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

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

    🗝️​​​​​​​进程跟踪状态 -- t🗝️

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

    • 首先我们在正常状态下查看这个进程的状态,其为 S睡眠状态。接下去呢我进行了【gdb】调试,在行内打上断点后,输入 运行起来后,我们再去查看这个进程的状态时,就发现其状态变成了t原因就在于这个进程在调试的时候停了下来

    🗝️​​​​​​​死亡状态 -- X 🗝️

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

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

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


    🗝️​​​​​​​僵死状态Z —— 两个特殊进程 🗝️

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

    ① 僵尸进程

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


    你呢,很喜欢晨跑🏃‍,这一天早晨6点又起来跑步了,当你路过一个公园的时候,遇到了一个晨练的【程序员】,边跑边掉头发😀 但是呢,跑着跑着,此时突然他就“啪叽”倒了下来。那你此时就非常担惊受怕了,马上拨打了110和120的电话,然后守在他的身边等待救援来到,周边的人看到也都纷纷围了过来,其中不免有一些人会紧急救援。不过等了一会这个人就没了呼吸🖤
     

    • 过了十几分钟后,救护车和警车都来了,警察先封锁了,让法医过来检验一下其状况,就说:“这个人已经没救了,赶紧通知家属准备后事吧~。”


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

    • 因为在救护车来之前这个人其实就已经死亡了,但是其状态还没有被检测,当前并不知道它的死因,所以我们操作系统就可能会维护当前的这个状态,这个状态即为Z状态,即[僵死状态]

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

    •  答:父进程!当一个进程退出的时候,那最关心它的便是【父进程】。因为这个父进程费了很大的劲才将这个子进程 fork 出来,此时呢它突然挂掉了,那么此时父进程就必须去关心一下对应的子进程退出时的原因

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

        #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 #include <sys/types.h>5 6 int Test1()7 {    8   pid_t id = fork();    9   if(id < 0)    10   {          11     //创建失败                                                                                         12     printf("创建fork失败!\n");13     return 1;           14   }                                 15   else if(id == 0)                16   {                                   17     //子进程暂停3s后终止18       printf("I'm child process, ");19       printf("pid:%d ", getpid());20       printf("ppid:%d \n", getppid());21       sleep(3);       22     return 0;23   }  24   else{                               25     //父进程死循环                 26     while(1)                          27     {          28       printf("I'am parent process, ");29       printf("pid: %d ", getpid());30       printf("ppid: %d\n", getppid());31       sleep(1);32     }33     return 0;34   }35 }36           37  38           39            40 int main()41 {42   Test1();43   return 0;44 }                    
    • 运行起来可以看到,在一开始的 3s 内,父子进程还是同时在跑的,但是当子进程在循环结束后退出了。不过此时呢父进程还在运行并没有退出。所以我们在右侧查看这两个进程的状态时间就发生了一定的变化

    仔细地来看一下这个状态的变化,其中【PID】 2815,其父进程 2814,一开始它们均为S 睡眠状态,但是呢到了后面子进程的状态就变成了Z僵死状态。也就意味着此时子进程已经死亡了,但是父进程还不知道
    这里还可以通过右侧的这个<defunct>这个来看,它表示【失效的、不再存在的】

     

    所以我们总结一下: 

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

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

    • 那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间
    • 那么对于上面的这种危害我们就称作为是【内存泄漏】,要如何去进行避免呢,之后的文章会做讲解~ 

     ② 孤儿进程
    • 上面我们讲到,当一个子进程突然退出但是父进程并没有去主动回收的话,那么此时这个子进程就会变成【僵尸进程】
    • 那看到下面我们将这个进程突然终止之后,父子进程都不见了

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

    因为当前这个进程是 bash 的子进程,当其一退出之后,bash 就将其回收了。可是这个子进程为什么也没了呢?这个的话我们就要聊聊【孤儿进程】了 


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

        #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 #include <sys/types.h>5 6 int Test1()7 {8   pid_t id = fork();9   if(id < 0)10   {11     //创建失败                                                                           12     printf("创建fork失败!\n");13     return 1;14   }15   else if(id == 0)16   {17     //子进程进入死循环18     while(1)19     {20       printf("I'm child process, ");21       printf("pid:%d ", getpid());22       printf("ppid:%d \n", getppid());23       sleep(1);24     }25     return 0;26   }27   else{28     //父进程暂停3s后终止    29       printf("I'am parent process, ");30       printf("pid: %d ", getpid());31       printf("ppid: %d\n", getppid());32       sleep(3);                                                                  33     return 0;34   }35 }36 37 38 39 40 int main()41 {42   Test1();43   return 0;44 }
    • 然后通过进程状态追踪来看看,我们观察到一开始两个父进程和子进程是同步在走的,但是呢过了一会父进程终止了,只有子进程还在跑,此时我们需要留意的不是其进程状态,而是这个子进程的 PPID 父进程的 PID它由原先的【22677】变成了【1】,这是为什么呢❓

    • 这里的话就要给读者普及一下了,对于PID的值为1的进程,我们一般将其称作为是【系统进程】。我们可以使用下面这句指令去查找一下
    ps ajx | head -1 && ps ajx | grep systemd
    
    • 然后我们看到这个【系统进程】的PID即为1

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

    •  对于父子进程来说,如果父进程先于子进程结束的话,那么这个子进程就会被称作为是【孤儿进程】,对于孤儿进程来说呢,它会有1号进程即【系统进程】所领养,因为此时这个进程没有了父进程了,所以需要有人去带领它 

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

    • 其实很简单,既然它是一个进程的话,最终都是要退出的,但是没了父亲的话就只能由系统进程来进行维护了

     四、总结

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

    在本文中,我们主要讲解了两个大点,一个是在操作系统中所常见的一些进程状态,它们分别为:运行状态、阻塞状态、挂起状态。 

    • 所被调度的、处于运行队列里的这些进程所处的状态我们称之为 运行状态R
    • 处于等待队列中,同时在等待外设相应的进程所处的状态我们称之为 阻塞状态R
    • 当把一个进程的 数据和代码都重新交换到外设当中,进程所处的状态我们称之为 挂起状态R


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

    • 当一个进程没有在等待IO流的时候,其就会处于 运行状态R
    • 使用 sleep() 函数可以很好地使一个进程处于浅度睡眠状态S
    • 如果不想让一个进程在等待磁盘操作的时候被操作系统杀掉,则可让其处于 深度睡眠状态D
    • 可以向一个进程发送【19】号信号使其暂停,处于停止状态T继续发送【18】号信号的话则可以使其重新启动
    • 【gdb】的环境下去运行一个断点的话则可以使其处于进程跟踪状态t
    • 使用kill -9 PID就可以杀掉一个进程,使其处于死亡状态X
    • 如果让一个子进程在父进程不知晓的时候退出,那么其就会处于僵死状态Z,变为【僵尸进程】;若是在父子进程中父进程先于子进程退出的话,那么这个子进程就会变成【孤儿进程】


    五、结束语

    以上就是我对【Linux系统编程】Linux下的七大进程状态 的理解

    感谢你的三连支持!!!

    http://www.dtcms.com/a/457724.html

    相关文章:

  • PostIn入门到实战(8) - 如何对接口进行全方位自动化测试,有效确保接口质量
  • 平顶山网站网站建设有赞小程序定制开发
  • 冲床电脑控制器说明书
  • 企业网站优化推广怎么做宁波信息港
  • SortedList
  • 【LeetCode热题100(37/100)】二叉树的最大深度
  • 茂名公司制作网站如何制作网站和软件
  • 网站的种类诺邯郸网站建设
  • 河北建设广州分公司网站黄浦网站设计
  • uniapp 设置主备请求地址切换
  • 深入洞察:华为数字化转型之战略规划
  • 集团网站 wordpress长春朝阳学校网站建设
  • 如何创立网站 优帮云wordpress用户注册插件下载
  • 【2026计算机毕设选题参考】Springboot项目 赋能AI
  • Windows下安装Miniforge3的指南(避坑anaconda收费)
  • Qt C++ :QLayout 布局管理
  • 网站下载app连接怎么做长沙房产
  • 内容网站设计范例百度直播推广
  • 基于AIGC的图表狐深度评测:自然语言生成专业级统计图表的技术实现
  • 怎样做京东网站iis做网站上传速度慢
  • 软考系规:基础篇核心知识整理及助记词分享
  • 5分钟上手 MongoDB:从零安装到第一条数据插入(Windows / macOS / Linux 全平台图解)
  • AI人工智能智域天演电子沙盘数字沙盘系统
  • 各大网站怎么把世界杯做头条泰安网络公司行情
  • 东莞市非凡网站建设网站建设员招聘
  • FreeRTOS任务同步与通信--任务通知
  • 从数据到智能:数据驱动时代下的技术实践与AI融合方法论
  • 2100AI相亲(二)
  • C++游戏编程入门(第三版)——Pong 项目(章节 6 - 7)
  • 网站建设工作动态网页设计需要学什么知识