【Linux操作系统】系统进程状态与类型详解
创始人
2024-09-26 00:19:28
0

目录

  • 一、进程状态概念
  • 二、Linux中的进程状态:
    • 1.就绪状态、运行状态(R)
      • 1.运行队列(进程排队)
      • 2.时间片
      • 3.进程的前后台运行
    • 2.挂起状态
    • 3.阻塞状态(S、D)
      • 1.可中断的睡眠状态(S浅度睡眠状态)
      • 2.不可中断的睡眠状态(D深度睡眠状态)
      • 3.关于S浅度睡眠状态与D深度睡眠状态的理解
    • 4.停止状态(T)、进程跟踪状态(t)
    • 5.死亡状态(X)
    • 6.僵死状态(Z)
      • 1.僵死状态的概念
      • 2.进程PID与退出码
      • 3.僵尸进程举例
      • 4.僵尸进程的危害
      • 5.僵尸进程的解决方案
    • 7.孤儿进程
      • 1.概念
      • 2.特点
      • 3.孤儿进程解决僵尸进程

一、进程状态概念

Linux进程状态是指Linux系统中进程所处的不同执行阶段或条件,状态决定了一个进程的后续动作

在Linux中,状态本质上是进程taskt_struct结构体中的一个整形变量
在这里插入图片描述

体现在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中的进程状态:

就绪状态(Ready):进程已经准备好执行但是还没有被处理器调度执行的状态

运行状态(Running):进程正在被处理器执行的状态

阻塞状态(Blocked):进程因为等待某些事件(如等待I/O操作完成、等待信号量等)而被阻塞的状态

等待状态(Waiting):进程因为等待某些事件(如I/O操作完成、信号等)而被阻塞的状态

暂停状态(Paused):进程被暂停执行,可以自行恢复执行

挂起状态(Suspended):进程被操作系统挂起执行,资源被释放,进程状态被保存到磁盘上。挂起状态可以分为内存挂起状态和磁盘挂起状态两种。

终止状态(Terminated):进程执行完毕或者因为某些原因被终止的状态

1.就绪状态、运行状态(R)

一个进程已经准备就绪,可以随时被系统调度此时就是运行状态
相当于合并了就绪和运行,统称运行状态

注意:不要认为被调度执行后才算运行状态

1.运行队列(进程排队)

我们知道,在等待运行时,进程需要排队等待被调度,就有一个就绪队列

但当内存中存在许多进程时就会使得CPU中的资源不够同时分配给许多进程,于是从就绪队列调度后仍然存在一个队列–运行队列

需要特别注意的是,在Linux中进程的任何排队操作,都是进程的PCB在排队,把所有的进程PCB用数据结构组织起来,就形成了我们的运行队列

这些存在运行队列中的进程都被称作运行状态

在这里插入图片描述
在这里插入图片描述

  • 不过一个进程的PCB可能不仅仅在一个队列中排队,在每个task_struct结构体中都会有很多的structural_listnode n,真正去排队的是这些东西,而不是之前的简化说法PCB

在这里插入图片描述

2.时间片

一个进程被拿到cup中执行时,并不是等这个进程执行完毕才切换下一个进程
而是这多个进程在一个时间段内所有代码都会被执行 —— 这就叫做【并发执行】
每一个进程执行一个时间片的时间后就会从cpu上拿下来,然后放上下一个进程。这个动作就称作为【进程切换】。
一个时间片通常是10ms左右

3.进程的前后台运行

1.前台进程

  • 指在终端中直接运行的命令或程序,它会占据当前终端,并将执行过程中产生的相关信息显示在终端上
  • 前台进程与用户进行交互,需要较高的响应速度,因此其优先级通常较高
  • 如果前台进程没有结束,用户则不能在当前终端中进行其他的操作

在Shell命令行中输入并执行某条命令,默认情况下会启动一个前台进程

2.后台进程

  • 也称为守护进程(Daemon),是运行在后台的一种特殊进程
  • 后台进程基本上不和用户交互,其优先级别相对较低
  • 后台进程不受终端控制,即使终端关闭,它也不会随之消失,而是继续运行
    在这里插入图片描述

在这里插入图片描述

比如我写了一个死循环,上面的状态显示的是R+

  • 这里的R+代表的就是这个进程是在前台运行的,所以我们在输入任何指令后不会对其造成任何的影响
  • 如果想要运行在后台,需要在执行时在你生成的可执行文件的后面加上了一个&,那么其状态变成了R,此代表的意思就是这个进程它是运行在了后台
    在这里插入图片描述
    在这里插入图片描述

2.挂起状态

挂起状态是一个重要的概念,它指的是将当前处于运行状态的数据保存在内存中,并让进程或系统等待某个事件的到来再继续执行,这相当于使计算机或进程进入一种睡眠状态

挂起状态分为系统挂起和进程挂起

1.系统挂起

  • 整个计算机系统进入挂起状态,此时CPU停止工作,内存中的数据被保存到磁盘中,以便在系统唤醒时能够快速恢复。
  • 系统挂起通常通过特定的命令或系统设置来实现,如使用rtcwake命令设置系统挂起时间。

2.进程挂起

  • 单个进程被挂起,暂停其所有活动并释放CPU时间片,但进程的状态信息和资源(如内存中的数据)仍然被保留。
  • 进程挂起可以由用户主动发起,也可能是操作系统因为资源不足或其他原因而自动进行。
  • 进程挂起可以通过发送特定的信号(如SIGSTOP)来实现,也可以通过其他机制(如调试器的暂停功能)来触发

3.挂起的场景与特点

  • 在挂起状态下,系统或进程占用的资源(如CPU、内存等)非常低,有助于释放系统资源给其他任务使用
  • 在资源有限的情况下,可以通过挂起非关键进程来释放资源给更重要的任务使用。

一般计算机处于挂起状态的前提是计算机的资源已经比较吃紧了,不得不将一些数据换到磁盘中(磁盘中的swap分区)

在这里插入图片描述

3.阻塞状态(S、D)

阻塞状态是进程在等待某个事件或资源(如I/O操作完成、信号量释放等)时所处的状态。

在这种状态下,进程无法继续执行,因为它需要等待的资源或事件尚未发生。

此时进程不会占用CPU资源,操作系统会调度其他可执行的进程

例如我们平时的命令行等待我们输入命令时就是一个阻塞状态

1.可中断的睡眠状态(S浅度睡眠状态)

S(sleeping)在本质上也是阻塞状态的一种,可以说是阻塞的一种分支

S状态是Linux中可中断的睡眠状态,表示进程正在等待某个事件或资源

S状态下的进程可以被信号或中断唤醒并继续执行。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

将进程运行起来我们可以看到其是S+的状态,因为命令行此时正在等待用户的输入,遇到I/O操作。

2.不可中断的睡眠状态(D深度睡眠状态)

D状态是Linux中不可中断的睡眠状态,也称为磁盘睡眠状态。在这种状态下,进程正在等待磁盘I/O操作或其他无法被中断的硬件操作完成。

进程无法响应任何信号或中断。

进程只能等待操作完成后才能继续执行。

3.关于S浅度睡眠状态与D深度睡眠状态的理解

学了挂起状态,我们可以知道,在内存不足时,会通过挂起状态来释放我们的内存

但是如果在极端情况下,即使挂起状态释放内存也不够呢?这时操作系统就没办法了,只能亲自动手开始杀进程了

但是这时用户有一个特别重要的信息要通过进程写入磁盘,但这个进程又刚好被操作系统杀了呢?这可就麻烦了,信息丢失可是个大问题

于是为了保证某些正在干重要事情的进程不被杀掉,给这些进程加了一块“免死金牌” D状态,操作系统在杀进程时,如果进程只是一个普通的‘S’,操作系统可以杀,但如果是‘D’,那么因为有免死金牌,操作系统不能杀

这个免死金牌具体来说就是给该进程的状态设置为深度睡眠状态。那么这个进程就不会被杀死了,当磁盘写完数据后告知进程,那么它就可以将自己放入【运行队列】里去运行,此时它的状态就变成R了

那如果D状态的进程特别多呢?

一般系统中D状态的进程是很少见的,如果你看到了D状态的进程,那就说明你的系统里挂不远了,洗洗睡吧

4.停止状态(T)、进程跟踪状态(t)

1.停止状态(T)

  • 停止状态(T)表示进程已经被停止执行。这通常是因为进程接收到了某种信号(如SIGSTOP)而主动或被动地停止了运行
  • 在停止状态下,进程不会占用CPU资源,也不会执行任何操作,直到它接收到继续执行的信号(如SIGCONT)或系统对其进行其他操作。

这种状态通常发生在以下情况下:

当进程读取一个设备,但是被设备拒绝了,而操作系统又不想杀掉你,此时,为了减少你的非法操作,就会把该进程置为停止状态。
当用户使用Ctrl+Z组合键将一个正在前台运行的进程移至后台时,该进程会进入停止状态

  • 在停止状态下,进程仍然存在于系统中,但不再活动。可以使用fg命令将一个停止的进程移回前台继续执行,或者使用bg命令将其放入后台执行。
  • 系统管理员可以使用kill命令的-STOP选项,或者kill -s SIGSTOP命令,将一个进程暂停
  • 暂停进程:kill -19 PID
  • 启动进程:kill -18 PID

处于暂停状态的进程,不仅仅是等待硬件资源,也可能是等待软件信号等,所以,他也可以被看作是一个阻塞状态的分支

2.进程跟踪状态(t)

  • 进程跟踪状态(t)是进程在被调试器跟踪时所处的状态。当使用调试器(如gdb)对进程进行调试时,如果调试器暂停了进程的执行(例如,在断点处),则进程会进入跟踪状态。
  • 在跟踪状态下,进程同样不会执行任何操作,但它与停止状态(T)的区别在于,跟踪状态是由调试器主动控制的,而停止状态则可能是由信号或其他外部因素触发的。
  • 比如调试器暂停了进程的执行。这通常发生在调试器设置了断点,并且进程执行到该断点时,或者调试器执行了其他导致进程暂停的操作,如单步执行等

T停止状态和S睡眠状态的主要区别在于:

  • T状态是进程被显式停止执行的状态,需要通过发送信号来恢复;
  • S状态是进程在等待某个事件或资源完成的状态,当等待条件满足时进程会自动恢复执行

5.死亡状态(X)

死亡状态就是所有资源释放进程的任务结束了,使这个进程退出,同时把这个进程的资源释放(通过父进程回收)
(就如一个人过世,处理好他的后事)

杀进程的方法:
1.发送9信号

kill -9 PID 

2.通过进程名、

killall 进程名 

在这里插入图片描述

6.僵死状态(Z)

1.僵死状态的概念

僵死状态形象点说有点像是没死透的死亡状态

进程在死亡后需要将进程的资源给父进程回收

简单说就是父进程既然创建了子进程后,定然会给子进程布置了任务,子进程完成任务后需要将任务的完成情况报备给父进程,否则父进程怎么知道你有没有好好完成任务呢?

因此,进程在退出后,却没有把进程的资源给父进程回收,此时的进程就处于僵死状态,此时的进程又被称作僵尸进程

2.进程PID与退出码

在系统中每个进程在创建时都会给进程分配一个PID,子进程的PID是父进程用来识别和操作子进程的唯一标识符

在退出时会返回给父进程的一个值,用于表示子进程的退出状态或执行结果。父进程通过读取子进程的退出码来获取子进程的结束信息
在这里插入图片描述
父进程回收子进程时会用wait函数回收子进程的PID,并将子进程的退出状态保存在通过第二个参数传递的地址中(如果提供了该参数)

3.僵尸进程举例

#include #include #include #include #include  int main() {    pid_t pid=fork();//创建父子进程     if(pid==0) //子进程进    {         //.......         printf("I am child, pid: %d, ppid: %d\n", getpid(), getppid());         exit(0);//返回退出码         //子进程结束    }     //父进程     sleep(15);     int status;     pid_t p=wait(&status);     printf("I am father, pid: %d, ppid: %d\n", getpid(), getppid());  } 

在sleep(15)前,子进程结束,但是还没有被父进程回收,显示的是Z+僵死状态
在这里插入图片描述
休眠15秒过后,父进程对子进程进行回收,子进程的僵死状态结束
在这里插入图片描述

4.僵尸进程的危害

如果一个父进程一直不去不去回收已经退出的子进程的信息,就会造成内存泄露

进程一般退出的时候,它的代码和相关数据会被释放,但是,它的task_struct对象依然还在内存中,仍然占用内存,占用进程表,这些僵尸进程会累积起来,占用大量的进程表项。
进程表是有限资源,当进程表被填满后,系统可能无法再创建新的进程,导致系统资源泄露和性能下降。

5.僵尸进程的解决方案

  1. 首先自然就是在子进程结束后让父进程用wait、waitpid回收
  2. 让父进程忽略 SIGCHLD信号,这样子进程结束后会被自动回收,不会变成僵尸进程
  3. 杀死父进程,让子进程成为孤儿进程,由 init 进程接管并回收

7.孤儿进程

1.概念

前面我们知道,僵尸进程是能够恢复的,只要被父进程回收就行

可万一,子进程好好地,父进程出事了呢?

父进程如果提前退出,子进程后退出,变成僵尸进程之后,那该如何处理呢?这种情况下的进程就称作孤儿进程

  • 孤儿进程不再拥有原来的父进程,因为父进程已经终止

2.特点

但其实这种情况比僵尸进程要好的多,因为在Linux系统中,存在init进程

  • 孤儿进程会被init进程收养。这意味着这些进程将以init进程作为它们的父进程继续运行
  • 当孤儿进程结束时,其占用的资源(如内存、文件描述符等)会被正常回收,就像任何其他进程一样
#include  #include  #include  int main() { 	pid_t id = fork(); 	if (id < 0) { 		perror("fork"); 		return 1; 	} 	else if (id == 0) {//child 		printf("I am child, pid : %d\n", getpid()); 		sleep(10); 	} 	else {//parent 		printf("I am parent, pid: %d\n", getpid()); 		sleep(3); 		exit(0); 	} 	return 0; } 

3.孤儿进程解决僵尸进程

甚至于如果出现了僵尸进程,我们还可以将僵尸进程的父进程杀掉,这样僵尸进程就会变成孤儿进程,这样就能正常被init进程回收

孤儿进程的存在通常不是一个问题,因为系统能够自动处理它们。然而,在某些情况下,如果系统中产生了大量的孤儿进程,并且这些进程长时间运行而不结束,那么它们可能会占用系统资源,影响系统性能

相关内容

热门资讯

安卓系统app更新软件,And... 亲爱的手机控们,你们有没有发现,最近你的手机里那些熟悉的APP们,好像都悄悄地换上了新装呢?没错,安...
手机怎么安双卡安卓系统,轻松实... 你有没有想过,拥有一部可以同时使用两张SIM卡的手机是多么的方便呢?想象一张卡用来工作,另一张卡用来...
安卓系统卸载软件api,功能与... 手机里的软件越来越多,是不是感觉内存都要不够用了?别急,今天就来给你揭秘安卓系统卸载软件的神秘面纱,...
miui操作系统和安卓系统,深... 亲爱的手机控们,今天咱们来聊聊一个让无数米粉心动的系统——MIUI操作系统,还有那个它背后的老大哥—...
原生安卓系统使用教学,原生安卓... 哇,你手里拿的那部手机,是不是也觉得它有点儿特别呢?它可能没有那些花里胡哨的界面,但它却有着自己独特...
安卓系统玩咸鱼之王,三国名将助... 你有没有发现,最近安卓系统上的游戏圈里,有一款叫做《咸鱼之王》的游戏火得一塌糊涂?没错,就是那个让你...
鸿蒙1.0系统是安卓系统吗,揭... 你有没有听说最近华为的鸿蒙1.0系统?是不是有点好奇,这鸿蒙1.0系统是不是安卓系统的“亲戚”呢?别...
优盘安卓系统用桃,U盘安装An... 你有没有想过,你的电脑也能变身成安卓手机?没错,就是那种可以安装各种APP、玩游戏的安卓手机!这可不...
怎样使用安卓8系统,安卓8系统... 你有没有想过,你的安卓手机其实是个小智能助手,只要你会使用,它能帮你做很多事情呢!今天,就让我来带你...
鼎威安卓系统版本,性能升级与用... 你有没有发现,现在车机系统越来越智能了?这不,鼎威的安卓系统版本就让我眼前一亮。想象坐在车里,手指轻...
安卓系统安装抢红包,轻松成为抢... 亲爱的手机控们,是不是每次微信群里抢红包都感觉手慢无?别急,今天我要给你揭秘如何在安卓系统上轻松安装...
写ios系统和安卓系统的人,揭... 你有没有想过,那些默默无闻的程序员们,他们是如何创造出我们每天离不开的iOS系统和安卓系统呢?想象他...
安卓系统设计尺寸规范,适配与优... 亲爱的设计师们,你是否在为安卓系统的设计尺寸规范而头疼?别担心,今天我要带你一起探索这个神秘的领域,...
旧主机改安卓系统,安卓系统改造... 亲爱的读者们,你是否有过这样的经历:家里的旧主机闲置在角落,看着它那略显过时的外观,心里不禁感叹:“...
安卓系统里有趣的,尽在掌握 探索安卓乐园:那些让你笑出声的趣味游戏 开篇:手机里的欢乐小天地想象你手握一部安卓手机,屏幕上跳动...
法兰规格查询系统安卓,安卓版功... 你有没有想过,在繁忙的工程现场,如何快速找到合适的法兰规格呢?别急,今天就来给你揭秘一个神器——法兰...
目前安卓系统最高配置,极致性能... 你有没有发现,现在的手机越来越厉害了,就像是科幻电影里的高科技产品一样。今天,咱们就来聊聊这个话题:...
安卓修改系统返回键,个性化设置... 你有没有发现,手机里的那个小小的返回键,有时候就像是个顽皮的小家伙,让你摸不着头脑?别急,今天就来教...
安卓订餐系统教程视频,从设计到... 你是不是也和我一样,每天忙碌的生活中,最期待的就是那一顿美味的午餐或晚餐呢?现在,有了安卓订餐系统,...
安卓系统限制外部软件,探索外部... 亲爱的手机控们,你是否曾遇到过这样的烦恼:明明打开了“未知来源”,却还是无法安装那些心仪的外部软件?...