【进程管理】进程状态

news2025/1/16 6:31:59

一.什么是进程状态

进程状态是PCB中定义的一个字段,具体到LInux操作系统,就是task_struct结构体中的一个变量,所谓的状态变化,本质就是修改整型变量。例如:

#define NEW 1

#define RUNNING 2

#define BLOCK 3

……

int status = 2;//运行状态

二.进程的三种状态

 

以上是在网上找的图,这些图基本都是教材上的,然而你会发现,不同教材进程的划分方式不一样,到底该听谁的呢?

其实不同的操作系统的状态分类是不一样的,但是原理都是大差不差,所以我们要做的就是学号原理。接下来我说的三种状态就是操作系统的原理层面,讲解完后我会再结合具体的LInux操作系统来分析,最终你会发现L虽然Inux操作系统的状态有那么多种,但都是从这三种上面衍生过来的。

1.运行状态

在操作系统内部,每个CPU都对应着一个运行队列,CPU和这个运行队列相关联,CPU要调度进程时直接到运行队列中获取

只要在运行队列中的进程 ,状态都是运行状态。也就是说运行状态不一定是真正意义上的运行,而是说这个进程已经准备好了,可以随时被调度。

2.阻塞状态

我们写的代码中,一定会或多或少地访问系统中的某些资源,比如磁盘,键盘,显示器等硬件设备。

加入代码中有一段使用scanf从键盘读取数据,代码跑到这就停了下来,等待用户输入数据。但我就是不输入,键盘上的数据没有就绪,不具备访问条件,进程的代码就无法向后执行。

进程要访问的资源没有就绪,操作系统要不要知道呢?当然要知道,不只要知道,所谓的不具备访问条件,就是操作系统告诉你的。操作系统不仅仅要进行进程管理,还有驱动管理来管理硬件。

和进程管理类似,要想对硬件进行管理,就得先描述再组织,所以每一个硬件设备也有对应的结构体来描述它的属性。所以硬件的资源有没有准备好,操作系统是一清二楚的。

操作系统是这样做的:当硬件资源没有就绪时,将进程的PCB从运行队列中移除,放到硬件设备的等待队列中,并将进程状态设为阻塞状态。当硬件资源就绪时,操作系统也是最先知道的,这时再将进程的PCB从等待队列移到运行队列,进程状态更改为运行状态,随时准备被调度。

没错,硬件也有自己的队列,事实上,操作系统中存在非常多的队列:CPU的运行队列,等待硬件设备的等待队列

这里我们得出一个重要结论:进程状态变化的本质就是:

  1. 更改PCB中的status整型变量
  2. 将PCB链入不同队列中

当一个进程阻塞了,我们看到了什么现象?为什么?

我们会看到进程卡住了,因为PCB不在运行队列中,进程不是运行状态,不会被CPU调度。

生活中,当我们执行多个下载任务时就会很卡,这是因为很多个进程都要向网卡获取数据,网卡忙到停不下来,很多进程大多数时候都处于阻塞状态。

补充说明:一个进程的PCB可同时在多个链表中

我们写的链表,next结点只有一个,因为结构体里的next指针只有一个,但是PCB在实现时,将prev,next这些链接字段又用了一层结构体封装了,所以一个PCB里可以有多个prev,next指针。

3.挂起状态

当一个进程阻塞了,注定了这个进程在它所等待的资源就绪之前,该进程是无法被调度的。如果此时,操作系统内的内存资源已经严重不足了,怎么办呢?操作系统是如何解决的?

当操作系统内存资源严重不足时,操作系统会将某些处于阻塞状态的进程的代码和数据置换到磁盘中,以腾出更多空间来使用,这时进程所处的状态就叫做阻塞挂起。当进程被调度,曾经被置换出去的进程代码和数据,又要被重新加载进来

问题一:这样不会变慢吗?

肯定是会变慢的,但这是操作系统生死存亡的时候啊,慢些又算得了什么呢?

问题二:数据换到哪里了?

换到了磁盘上的swap分区。建议不要把swap分区设置得太大,因为空间太大了,操作系统会更加依赖这种挂起进程获得空间的方式,频繁地和磁盘交换数据会降低效率。swap分区设置成和内存大小一样即可。

三.Linux操作系统的进程状态

以下内容来自Linux某个版本的源代码:

static const char * const task_state_array[] = 
{
    "R (running)",
    "S (sleeping)", 
    "D (disk sleep)", 
    "T (stopped)",
    "t (tracing stop)",
    "X (dead)", 
    "Z (zombie)", 
};

1.R运行状态

写一段平平无奇的helloworld,运行后打开另一个窗口,用ps命令查看一下

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

while :; do ps ajx | head -1 && ps ajx | grep code |grep -v "vim" | grep -v "grep" ; sleep 1; echo "###########################################"; done

用这样一段Shell脚本来监控进程,也就是一秒钟打印一下信息。

然后发生了戏剧性的一幕,左边code进程在疯狂刷屏,右边进程的stat怎么不是R呢?这个S+是个什么鬼?

S是休眠状态,就是一种特殊的阻塞状态。因为printf操作是在访问显示器外设,在执行IO操作,IO操作和CPU处理处理速度相比是很慢的,所以这个进程大多数时间是在阻塞状态等待显示器就绪的。而监控脚本一秒钟打印一次,所以检测到运行状态的概率很小。

  1 #include <stdio.h>
  2 
  3 int main()
  4 {
  5     while (1)
  6     {
  7     }
  8     return 0;
  9 }

当把printf去掉,再次运行代码,监控进程,得到的结果就是这样的了:

为什么是S理解了,但后面加号是什么呢?+表示这个进程是前台进程。这种进程一旦启动就会导致命令行解释器无法接收命令,并且可以Ctrl + C终止的,就叫做前台进程。要想一个进程在后台运行,只需启动时加上&。后台进程运行时,我们仍然可以在命令行中输入命令,并且这种进程不能用Ctrl + C终止,但是可以用kill命令杀死

./code &

2.S睡眠状态

前面讲的阻塞状态是一种统称,具体到Linux系统,S睡眠状态就是所说的阻塞状态。S状态是一种浅度睡眠,会对外部信号做出反应,可以被kill掉。与浅度睡眠相对的还有深度睡眠

3.D磁盘休眠状态

D休眠状态也是阻塞状态,它是一种深度睡眠,是专门针对磁盘来设计的。D状态是为了防止进程向磁盘写入关键数据时,该进程被操作系统杀掉而导致数据丢失。深度睡眠的进程不可被杀掉,即使是操作系统也不行。只有这个进程完成了写入工作自动醒来,除此之外没有任何办法,关机都关不了。

一般而言,D状态我们是查不到的。如果你查到了D状态,说明你的磁盘已经非常忙了,计算机快要挂掉了。

4.T停止状态

kill不仅可以杀死一个进程,也可以把一个进程暂停,使其进入T停止状态。

kill -l

如图可以使用kill指令给进程发送各种信号,前面是编号,后面是名称。这些信号其实是操作系统中的宏定义。其中19号信号就能使进程stop。

kill -SIGSTOP [pid]

kill -19 [pid]

以上两个指令都能暂停一个进程,但这个进程并没有被杀死,如果它是前台进程,就会将它移到后台。

kill -SIGCON [pid]

这个指令可以解除进程的暂停状态,使其继续运行。

S状态存在的意义是什么呢?

在进程访问软件资源的时候,操作系统可能暂时不让进程访问,就将进程设为T停止状态

T状态和D状态一样,用户基本是见不到的。

5.t追踪停止状态 

T和t可以基本看成是同一个状态,T不常见,当t比较常见。

例如用gdb来debug程序时,追踪程序,遇到断点,进程就暂停了,此时就处于t状态。

其实T/t状态也是一种阻塞状态,进程debug时停下来,其实是在等待gdb给它下一步的指令,是在等待gdb这个软件(进程)的资源。当我们输入n给gdb,gdb就会给进程发送kill SIGCON指令,软件资源就绪,进程又会继续运行。

所以说等待队列不只是CPU和各种硬件设备拥有,进程PCB也是可以有自己的等待队列的!进程也可以等待另一个进程

6.X死亡状态

当一个进程结束时就处于X状态,这是一个瞬时状态,用户很难查到

7.Z僵尸状态

我们创建一个进程的目的是什么?是为了完成某项任务。那么一个进程在退出时,是不是理应告诉我任务完成的情况如何呢?是这样的。

当一个进程退出后,它的退出信息会被操作系统写入到进程PCB中,进程的代码和数据会被立即释放,但是PCB仍然被操作系统维护。只有父进程读取了退出信息,得知进程的退出原因,PCB才会被释放。像这种进程已经退出,但是退出信息未被父进程读取,PCB一直存在的进程就叫做僵尸进程,所处的状态就做僵尸状态。当退出信息被读取之后,操作系统会先将PCB设为X状态,然后释放PCB。

僵尸进程的危害是什么? 

一个进程已经退出,但是它的父进程就是不读取退出信息,PCB就会一直存在,占用内存空间,造成内存泄漏。

四.孤儿进程

当一个进程的父进程退出时,他就变成了孤儿进程。孤儿进程必须要被领养,否则他的退出信息无法被读取,会一直处于僵尸状态,造成内存泄漏。孤儿继承统一被一号进程systemd领养,1号进程就是操作系统

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1111530.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【javascript】内部引入与外部引入javascript

创建a.html 内部引入&#xff1a; 外部引入&#xff1a; 创建a.js 注意&#xff1a; 我这里的a.js和a.html是放在同一个目录下&#xff0c;如果a.js放在js的目录下&#xff0c;a.html 调用a.js的时候 <script src"/js/a.js"></script>

【C++中cin、cin.get()、cin.getline()、getline() 的区别】

文章目录 引入cin基本用法输入多个变量换行符存放在缓冲区中 cin.get()基本用法重载函数换行符残留在缓冲区中 cin.getline()基本使用重载函数换行符不会残留在缓冲区中 string 流中的 getline()总结用法总结几个输入实例输入格式输入格式输入格式输入格式 输出格式 写在最后 引…

【毕业设计】基于SSM的商城系统

前言 &#x1f525;本系统可以选作为毕业设计&#xff0c;运用了现在主流的SSM框架&#xff0c;采用Maven来帮助我们管理依赖&#xff0c;所选结构非常合适大学生所学的技术&#xff0c;本系统结构简单&#xff0c;容易理解&#xff01;本系统功能结构完整&#xff0c;非常高适…

发展新能源汽车加快充换电基础设施建设实施方案-安科瑞黄安南

摘要&#xff1a;为深入贯彻落实《国务院办公厅关于印发新能源汽车产业发展规划&#xff08;2021—2035年&#xff09;的通知》&#xff08;国办发 ﹝2020﹞39号&#xff09;、《国家发展改革委等部门关于进一步提升电动汽车充电基础设施服务保障能力的实施意见》&#xff08;发…

【疯狂Java讲义】Java学习记录(使用jar命令打包)

jar命令 把多个文件打包成一个压缩包——这个压缩包和WinZip的压缩格式是一样的。 区别在于jar压缩的文件默认多一个META-INF的文件夹&#xff0c;该文件夹里包含一个MANIFEST.MF的文件&#xff08;清单&#xff09;。 通常来说&#xff0c;得到的压缩包有3种&#xff08;压缩格…

机器学习tip:sklearn中的pipeline

文章目录 1 加载数据集2 构思算法的流程3 Pipeline执行流程的分析ReferenceStatement 一个典型的机器学习构建包含若干个过程 源数据ETL数据预处理特征选取模型训练与验证 一个典型的机器学习构建包含若干个过程 以上四个步骤可以抽象为一个包括多个步骤的流水线式工作&…

Ubuntu安装和配置ssh

一般Ubuntu都会默认安装openssh-client,但是没有安装openssh-server。 一、安装ssh服务器 sudo apt install openssh-server 二、安装ssh客户端 sudo apt install openssh-client 三、 配置ssh客户端,去掉PasswordAuthentication yes前面的#号,保存退出 sudo vi /etc/ssh…

mysql按照日期分组统计数据(date_formatstr_to_date)

学习链接 mysql按照日期分组统计数据 博主-山茶花开时的 【Mysql专栏学习】 mysql按照日期分组统计数据 Mysql的date_format函数想必大家都使用过吧&#xff0c;一般用于日期时间转化&#xff0c;如下所示 # 可以得出 2023-01-01 08:30:50 select DATE_FORMAT(2023-01-01…

NodeMCU ESP8266 的PWM波形输出教程(图文并茂)

NodeMCU ESP8266 基于 Arduino 的 PWM波形输出 文章目录 NodeMCU ESP8266 基于 Arduino 的 PWM波形输出什么是PWM?常用接口pinModeanalogWrite 示例总结 什么是PWM? PWM是脉冲宽度调制&#xff08;Pulse Width Modulation&#xff09;的缩写&#xff0c;是一种用于控制电子设…

百度的新想象力在哪?

理解中国大模型&#xff0c;百度是一个窗口。这个窗口的特殊性不仅在于变化本身&#xff0c;而是在于百度本身就是那个窗口。 作者|皮爷 出品|产业家 沿着首钢园北区向西北步行10分钟&#xff0c;就能看到一个高约90米的大跳台&#xff0c;在工业园钢铁痕迹的印衬下&#…

9.构造器与垃圾收集器 对象的前世今生

9.1 对象与变量的生存空间 栈与堆&#xff1a;生存空间 在Java中&#xff0c;程序员会在乎内存中的两种区域&#xff1a;对象的生存空间堆&#xff08;heap&#xff09;和方法调用及变量的生存空间&#xff08;stack&#xff09;。当Java虚拟机启动时&#xff0c;它会从底层的…

CSS之Flex布局的详细解析

Flex布局 目标&#xff1a;熟练使用 Flex 完成结构化布局 01-标准流 标准流也叫文档流&#xff0c;指的是标签在页面中默认的排布规则&#xff0c;例如&#xff1a;块元素独占一行&#xff0c;行内元素可以一行显示多个。 02-浮动 基本使用 作用&#xff1a;让块元素水平排列…

【生成模型】DDPM概率扩散模型(原理+代码)

--- 前言一、常见生成模型二、直观理解Diffusion model三、形式化解析Diffusion model*四、详解 Diffusion Model&#xff08;数学推导&#xff09;1.前向过程(扩散过程)2.逆扩散过程3.逆扩散条件概率推导4.训练损失 五、训练、测试伪代码1. 训练2.测试 六、代码解析1.train_ci…

进程的描述、控制与通信

一、概念 进程的状态 进程的最基本状态 就绪态执行态阻塞态 为保证完整性&#xff0c;再引入两种状态 创建态终止态 引入挂起操作后&#xff0c;引入的状态 活动就绪静止就绪活动阻塞静止阻塞 挂起&#xff1a;当挂起操作作用于某个进程时&#xff0c;该进程将被挂起&…

基于LSTM时间序列预测(简单又好用)无脑代码

# 基于LSTM时间序列预测&#xff08;简单又好用&#xff09;无脑代码&#xff0c; 这里是列表文本使用很简单&#xff0c;跟着注释和使用手册用就行. 简介&#xff1a; 1、单变量&#xff0c;多变量输入&#xff0c;自由切换 2、单步预测&#xff0c;多步预测&#xff0c;自动…

1.集合框架

一、JDK版本之间的关系 1.1、Oracle JDK与OpenJDK的区别 1.Oracle JDK是基于OpenJDK源代码构建的&#xff0c;因此Oracle JDK和OpenJDK之间没有重大的技术差异。 2.Oracle JDK将更多地关注稳定性&#xff0c;它重视更多的企业级用户&#xff0c;而OpenJDK经常发布以支持其他性能…

电子技术基础(三)__第7章 时序逻辑电路_第6篇__时序逻辑电路的分类

时序逻辑电路的分类&#xff0c; 通常按两种来分类&#xff1a; 按逻辑功能&#xff0c; 按触发器状态的变化规律。 一. 同步、异步的定义 同步时序逻辑电路 是 所有触发器有一个共同的时钟控制信号CP, 在CP脉冲信号的作用下&#xff0c;触发器状态的变化同时发生&#xff0c;…

40G光模块的兼容性与协议标准

40G光模块的兼容性与标准化是确保光通信系统稳定运行的关键因素。在下文中&#xff0c;易天光通信将对40G光模块的兼容性和标准化进行分析和讨论。 一、关于40G光模块的兼容性方面 40G光模块的兼容性主要涉及两个方面&#xff1a;光接口的兼容性和协议的兼容性。 光接口兼容…

零基础如何自学C#?

前言 本文来源于知乎的一个提问&#xff0c;提问的是一个大一软件工程专业的学生&#xff0c;他想要自学C#但是不知道该怎么去学&#xff0c;这让他感到很迷茫&#xff0c;希望有人能给他一些建议和提供一些学习方向。 个人建议 确认目标&#xff1a;自学C#首先你需要大概了解…

“第四十四天”

这道题也不是难&#xff0c;但可能会忽略一种情况&#xff0c;当最大小出现在首位的时候&#xff0c;那个时候如果进行交换的话&#xff0c;大小值可能出现覆盖的情况&#xff0c;最终导致丢失最大值或者最小值&#xff0c;比如最大值 10 在第一位&#xff0c;最小值 0 随意&am…