Linux:理解进程的多种状态

文章目录

  • 理解状态
  • 运行状态
  • 阻塞状态
  • 挂起状态
  • Linux系统下的进程
    • 状态的解析
    • 状态的查看

本篇总结的是进程的多种状态

对于进程的状态理解,在教材上通常是有下面的思维模式图

在这里插入图片描述
那么如何理解上面图片中的内容?

理解状态

如何理解状态?其实理解状态很简单,状态就是PCB中的一个变量,例如说在PCB中,可能会有一个变量定义为 int status,而在代码外面定义

#define NEW 1
#define RUNNING 2
#define BLOCK 3

由此可以可以借助上面的宏定义,将状态进行修改

pcb->status=NEW;
...

因此,所谓状态的变化过程,实际上就是修改整形变量的过程,通过修改整形变量就可以实现修改状态,那这个状态表示有什么用?

if(pcb->status == NEW)
{// PCB进入运行队列...
}
else if(pcb->status == BLOCK)
{// PCB进入阻塞队列...
}

进程的状态,其实就是PCB的一个变量,因此状态只和PCB有关系,和代码数据无关

运行状态

运行状态是进程多种状态中的一种,那如何理解运行状态?

只要在运行队列中的进程,状态都是运行状态

上面是对于运行状态的定义,但是又引入了新的概念,什么是运行队列呢?

通常来说,一个CPU可以负责管理一个运行队列,这里默认设备是一个单核的设备,那么CPU和内存和操作系统的管理方式如下所示:

在这里插入图片描述
每个CPU在系统层面上都会维护一个运行队列

对于上图来说,CPU就进行维护了一个runqueue队列,这个队列管理了一串PCB,而这当中的每一个PCB又进行管理了它们对应的可执行程序,此时,每一个可执行程序对应的PCB中的status数据都是NEW,代表着这些程序是正处于运行状态,是可以被随时调度的,因此上面这些概念再结合上图其实就是运行状态的概念

阻塞状态

总结了运行状态,就要进行阻塞状态的学习,那什么是阻塞状态?

以下面的例子为例:

#include <stdio.h>int main()
{int a;scanf("%d",&a);printf("%d",a);return 0;
}

这是一个很简单的程序,输入一个值,再将这个值输出,当开始运行的时候这个程序就进入了内存中,操作系统为它生成了PCB进行管理它,此时它就变成了一个进程,但是如果一直不输入值,换句话说,键盘上面的数据没有就绪,因此进程要访问的资源没有就绪,此时进程的代码就不能向后执行,这样就被称之为阻塞状态

操作系统作为管理的软件,自然是会在第一时间知道这件事的,它马上知道这个进程不能正常进行了,被阻塞了,因此就把状态修改为BLOCK,但这并没有结束,操作系统在修改状态的同时就要将这个进程移除运行队列,那移动到哪里?答案是等待队列

那又引入了一个新词,什么是等待队列?这就要回到前面的问题,阻塞状态是如何产生的?

在我们写的代码中,一定会有一些代码是需要访问系统的资源的,比如说最简单的输入输出需要用到键盘和显示器,甚至有些代码还可能用到磁盘网卡等各种硬件的设备,换种角度来讲,从本质来看,是用户想要从这些硬件中获取到用户想要的信息,但是现在用户不输入,键盘的数据没有准备就绪,那么进程需要从scanf中得到的数据就没有就绪,因此就不具备访问的条件,进程的代码不能正常进行,而此时操作系统是知道这件事的,因为在操作系统的底层逻辑中它是可以管理到整个软硬件资源的,因此针对这种硬件设备异常的问题,操作系统也有自己的解决方法

操作系统会将它所管理的硬件设备也进行描述,对硬件设备构建属于它们自己的结构体,因此有了下面的演示:

在这里插入图片描述
操作系统会对它所管理的硬件设备也创建它的描述,这里叫为dev,在这个结构体中也会描述一系列状态,比如说类型,对应到底是什么设备,比如状态,对应现在硬件的情况是什么,比如指针,可以将数据连起来可以进行链式访问,还有下面要提到的wait_queue

前面提到,当一个运行状态的进程被判定为现在是阻塞状态时,它就已经不能再在运行队列中了,那么它应该去哪里呢?这就引出了等待队列的概念,当进程进入阻塞状态的时候,它就会被放到等待队列中进行等待

在这里插入图片描述
而当阻塞队列中的进程的状态回到运行状态了,就可以将阻塞队列的进程再拿回到运行队列中即可

因此,进程状态变化的本质?

  1. 更改PCBstatus的变量
  2. PCB连入不同的队列中

而由此可以得出一个结论:在操作系统中,会存在非常多的队列,运行队列,等待硬件的设备等待队列等,所有系统内的进程都是用双链表链接起来的

挂起状态

什么是挂起?

前面明确一个概念,如果进程处于阻塞状态,那么就说明,此时此刻它所等待的资源在没有就绪的时候,这个进程是不能被调度的,但这个进程现在依旧处于内存中,如果数量比较少不会造成什么影响,如果数量到达一定程度以至于操作系统内的资源已经严重不足得时候,这时会怎么办?

在这里插入图片描述
对于这种情况,操作系统的选择是,将内存数据置换到外设,这个操作是针对所有的阻塞进程的,如下图所示:

在这里插入图片描述
交换的位置在哪里?操作系统将信息转移到了swap分区内,当进程被操作系统调度的时候,被加载到这些分区的代码和数据就会被重新加载进来,也就是说,这是一个换入和换出的过程,而将信息交换到磁盘上后进程的状态,就被称之为挂起状态

弊端在于哪里?

这样的行为一定是有弊端的,由于牵扯到数据的输入和输出的过程,这个过程一定会导致效率降低,但是这是操作系统为了保证整个系统的良好运行而做出的选择,如果不做出这个选择那么整个系统都有挂掉的风险,因此在实际的开发中,swap分区的大小通常设置和内存的大小一样即可

Linux系统下的进程

本篇在总结操作系统的概念中,大多数情况下是根据的是Linux下的系统,那么就需要具体的进入操作系统的源代码中去寻找具体的信息:

Linux中进程的状态表示

/** The task state array is a strange "bitmap" of* reasons to sleep. Thus "running" is zero, and* you can test for combinations of others with* simple bit tests.*/
static const char *task_state_array[] = {"R (running)",		/*  0 */"S (sleeping)",		/*  1 */"D (disk sleep)",	/*  2 */"T (stopped)",		/*  4 */"T (tracing stop)",	/*  8 */"Z (zombie)",		/* 16 */"X (dead)"		/* 32 */
};

从上面的学习中知道,进程有运行状态,阻塞状态和挂起状态,那么落实到Linux内核源码中,它的实现也是要根据这个原理进行设计

例如在上面的源码中看到,有running状态,也有sleepingdisk sleep状态,也有stoppedtracing stop状态,也有zombiedie状态,下面就对这些状态进行分析:

状态的解析

  1. R运行状态:表示的是进程在运行中或者是在运行队列中,也不一定是一定表示为在运行中
  2. S睡眠状态:表示的是进程正在等待一个事件的完成
  3. D磁盘休眠状态:表示的是不可中断睡眠状态,后面进行详解
  4. T停止状态:表示进程被停止了,可以通过信号重新启动等等
  5. X死亡状态:表示进程被杀死了

状态的查看

对于状态的查看可以使用定时脚本来实时监测状态,以及使用ps指令来进行监视状态

首先写一个C程序死循环,这样可以实时监测到运行状态

#include <stdio.h>
#include <unistd.h>int main()
{while(1);return 0;
}
# 运行程序
[test@VM-16-11-centos process]$ vim process.c
[test@VM-16-11-centos process]$ make
gcc -o process process.c
[test@VM-16-11-centos process]$ ./process# 使用脚本观察进程状态PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND365  2397  2397   365 pts/0     2397 R+    1003   0:05 ./process

此时对于状态一栏显示的是R+,那么加号代表什么意思?

Linux中的进程也分为很多种,比如说有前台进程和后台进程,那么带加号的进程就被称为前台进程,前台进程和后台进程最明显的一个区别是,不能输入指令供bash来解释

Linux中,可以使用&

在这里插入图片描述
但对应的问题是使用Ctrl+C不可以终止程序,需要用kill命令来终止进程

休眠状态

Linux中还存在休眠状态的进程,其实也就对应着阻塞状态的进程,在这个状态下的进程是不会被运行的,而休眠状态也有两种,浅度睡眠和深度睡眠

浅度睡眠

以前面举的例子为例,当现在运行的程序需要输入一个值的时候,此时如果用户一直不输入值,那么程序就会从运行队列踢出,在等待队列进行等待,此时程序就处于阻塞状态,但如果此时Linux系统的运行压力过大,它是可以通过杀掉进程来节省资源的

杀掉进程的代价是很大的,如果进程只是一些运行的程序还不算很大损失,但如果是向磁盘写入信息?对于这个进程来说,如果被杀掉了进程,那么对于用户来说是很大的损失

深度睡眠

因此为了避免这样的情况出现,Linux系统刻意创建了一个disk sleep状态,它被叫做磁盘睡眠状态,是专门为了磁盘来设计的,也叫做深度睡眠状态,对于进入深度睡眠状态的进程来说,它是不会被随意终止的,操作系统也没有权力对这种状态的进程做操作,这样做的目的就是为了保护和磁盘进行数据交互的进程被操作系统意外终止

终止

Linux中存在一个状态是Tt状态,现在几乎对这两个系统不做太多区分,这两个状态都是对进程进行暂停,tracing stop更指向的是对进程进行追踪,例如在debug模式下追踪断点的这个过程

为什么?

由于在进行软件资源访问的时候,可能会需要暂时对进程停止访问,就将进程设置为STOP即可

实际运用?

Linux的调试工具gdb中,有一个操作叫做打断点,而打断点的实质就是在debug程序的时候,可以追踪程序,如果遇到断点,进程就停止了,也就是说调试程序实际上就是进程在运行,而打断点停下来的过程实际上就是进程被终止的过程

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyCharm中使用pyqt5的方法2-2

1.2 是否下载成功 按照以上步骤安装了“pyqt5”、“pyqt5-tools”模块和“pyqt5designer”模块后&#xff0c;可以打开保存这三个模块的路径&#xff0c;找到其对应的文件夹&#xff0c;即可验证是否下载成功。 获取PyCharm保存下载模块路径的方法是&#xff0c;在PyCharm界面…

解决java.io.FileNotFoundException: HADOOP_HOME and hadoop.home.dir are unset.的错误

文章目录 1. 复现错误2. 分析错误3. 解决问题3.1 下载Hadoop3.2 配置Hadoop3.3 下载winutils3.4 配置winutils 1. 复现错误 今天在运行同事给我的项目&#xff0c;但在项目启动时&#xff0c;报出如下错误&#xff1a; java.io.FileNotFoundException: java.io.FileNotFoundEx…

【AI视野·今日NLP 自然语言处理论文速览 第四十二期】Wed, 27 Sep 2023

AI视野今日CS.NLP 自然语言处理论文速览 Wed, 27 Sep 2023 Totally 50 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Attention Satisfies: A Constraint-Satisfaction Lens on Factual Errors of Language Models Authors Mert …

苹果 CMS 原生 Java 白菜影视 App 源码【带打包教程】

苹果 CMS 原生 Java 白菜影视 App 源码是一款功能强大的影视应用程序&#xff0c;支持画中画、投屏、点播、播放前广告和支持普通解析等多种功能。与萝卜 App 源码相比&#xff0c;该套源码更加稳定&#xff0c;且拥有画中画投屏和自定义广告等功能&#xff0c;提高了安全性。 …

河北吉力宝以步力宝健康鞋引发的全新生活生态商

在当今瞬息万变的商业世界中&#xff0c;成功企业通常都是那些不拘泥于传统、勇于创新的先锋之选。河北吉力宝正是这样一家企业&#xff0c;通过打造一双步力宝健康鞋&#xff0c;他们以功能性智能科技穿戴品为核心&#xff0c;成功创造了一种结合智能康养与时尚潮流的独特产品…

Leetcode算法入门与数组丨5. 数组二分查找

文章目录 1 二分查找算法2 二分查找细节3 二分查找两种思路3.1 直接法3.2 排除法 task09task10 1 二分查找算法 二分查找算法是一种常用的查找算法&#xff0c;也被称为折半查找算法。它适用于有序数组的查找&#xff0c;并通过将待查找区间不断缩小一半的方式来快速定位目标值…

Redis 线程模式

Redis 是单线程吗&#xff1f; Redis 单线程指的是 [接收客户端请求 -> 解析请求 -> 进行数据读写操作 -> 发送数据给客户端] 这个过程是由一个线程 (主线程) 来完成的&#xff0c;这也是常说的 Redis 是单线程的原因。 但是 &#xff0c;Redis 程序不是单线程的&am…

VB从资源文件中播放wav音乐文件

Private Const SND_SYNC &H0 Private Const SND_MEMORY &H4 API函数 Private Declare Function sndPlaySoundFromMemory Lib "winmm.dll" Alias "sndPlaySoundA" (lpszSoundName As Any, ByVal uFlags As Long) As Long 音乐效果请“单击” Pr…

美国零售电商平台Target,值得入驻吗?如何入驻?

Target 是美国最大的零售商之一&#xff0c;在品牌出海为大势所趋的背景下&#xff0c;它在北美电商中的地位节节攀升。Target 商店在众多垂直领域提供各种价格实惠的自有品牌&#xff0c;吸引越来越多的跨境商家入驻&#xff0c;如美妆、家居、鞋服、日用百货等&#xff0c;随…

在比特币上支持椭圆曲线 BLS12–381

通过使用智能合约实现来支持任何曲线 BLS12–381 是一种较新的配对友好型椭圆曲线。 与常用的 BN-256 曲线相比&#xff0c;BLS12-381 的安全性明显更高&#xff0c;并且安全目标是 128 位。 所有其他区块链&#xff0c;例如 Zcash 和以太坊&#xff0c;都必须通过硬分叉才能升…

Android Studio 创建项目不自动生成BuildConfig文件

今天在AS上新建项目发现找不到BuildConfig文件&#xff0c;怎么clear都不行。通过多方面查找发现原来gradle版本不同造成的&#xff0c;Gradle 8.0默认不生成 BuildConfig 文件。 如上图&#xff0c;8.0版本是没有source文件夹 上图是低于8.0版本有source文件夹 针对这个问题&…

Anchors

这是源代码定义的anchors概念&#xff1a; 实现过程&#xff1a; 假如有一张500500的图片&#xff0c;那么经过第一步深度卷积网络之后&#xff08;4次池化&#xff09;&#xff0c;最终就会变成一个3232的特征&#xff1a; 在开源代码实现里面&#xff1a; 所以经过卷积完之后…

D. A Simple Task

Problem - D - Codeforces 思路&#xff1a;这个题就是求环的数量&#xff0c;通过数据范围的大小&#xff0c;我们可以想到用状压dp来做&#xff0c;因为只有19个点&#xff0c;我们可以将环的路径进行状态压缩&#xff0c;用一个二进制数表示环&#xff0c;当某一位为1时表示…

3、组件和容器

3、组件和容器 Frame 万物皆对象&#xff0c;窗口也是一个对象&#xff0c;这里Frame也是一个对象&#xff0c;我们可以看到Frame是可以new出来的&#xff0c;它是属于java.awt包下的 学习中想要知道这个类怎么用可以采用查JDK帮助文档&#xff0c;这里推荐查看源码&#xff0…

解决 MyBatis-Plus 中增加修改时,对应时间的更新问题

问题&#xff1a;在添加修改时&#xff0c;对应的 create_time 与 insert_time 不会随着添加修改而自动的更新时间 第一步&#xff1a;首先在对应的属性上&#xff0c;加上以下注解 如果只添加以下注解&#xff0c;在增加或者修改时&#xff0c;可能对应的 LocalDateTime 会出…

Unity中Shader需要了解的点与向量

文章目录 前言一、点和向量的区别二、向量加法减法1、向量加法2、向量减法(可以把向量减法转化为向量加法) 三、向量的模四、标量![在这里插入图片描述](https://img-blog.csdnimg.cn/03df81df3cdf47989a11605d5f5e7da5.png)1、向量与标量的乘法 前言 Unity中Shader了解使用的…

使用Python做一个微信机器人

介绍 简介 该程序将微信的内部功能提取出来&#xff0c;然后在程序里加载Python&#xff0c;接着将这些功能导出成库函数&#xff0c;就可以在Python里使用这些函数 程序启动的时候会执行py_code目录下的main.py&#xff0c;类似于你在命令行使用python main.py。 现在会以…

windows11系统没有系统散热方式的解决办法

一、问题描述 当我们查看Win11系统的&#xff08;同时按下键盘的WinR键即可打开运行窗口&#xff09;【控制面板】-->【硬件和声音】-->【电源选项】-->【更改计划设置】-->【 更改高级电源设置】-->【处理器电源管理】下没有系统散热方式的选项&#xff0c;如下…

【C语言】【结构体的内存对齐】计算结构体内存大小,有图解

计算结构体内存大小&#xff0c;需要用到结构体内存对齐的知识 来段代码看看什么是结构体对齐&#xff1a; #include<stdio.h> struct S1 {char a;char b;int num; }; struct S2 {char a;int num;char b; }; int main() {printf("%zd\n", sizeof(struct S1))…

Armv9 Cortex-A720的L2 memory system 和 L2 Cache

9 L2 memory system Cortex-A720核心的L2内存系统通过CPU bridge连接core与DynamIQ Shared Unit-120,其中包括私有的L2缓存。 L2缓存是统一的,每个Cortex-A720核心在一个集群中都有私有的L2缓存。 L2内存系统包括使用虚拟地址(VA)和程序计数器(PC)的数据预取引擎。不同…