Linux进程状态及优先级

news2024/9/27 12:15:09

进程状态及优先级

本文已收录至《Linux知识与编程》专栏!
作者:ARMCSKGT
演示环境:CentOS 7

在这里插入图片描述


进程状态及优先级

  • 前言
  • 正文
    • 进程状态
      • 就绪运行状态R
      • 阻塞
        • 睡眠状态 S
        • 休眠状态D
        • 挂起
      • 暂停状态T
        • 前台与后台进程
        • 待追踪暂停状态t
      • 死亡状态 X
      • 僵尸状态 Z
    • 孤儿进程
    • 进程优先级
      • 查看进程优先级
      • 修改进程优先级
  • 最后


前言

操作系统想管理好进程并不简单,对于Linux系统将进程分为不同的状态进行管理;例如运行,阻塞,休眠状态等等,每一种状态都有不同的效果,这样才能发挥他的全部功效,且进程之间也有优先级,本文将为您详细讲解!
进程状态图


正文

进程状态


为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在Linux内核里,进程有时候也叫做任务)。

进程状态

下面是进程状态在kernel源代码中的定义:

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

分别对应:

  • R(就绪运行状态)
  • 阻塞状态
    – S(睡眠状态/可中断睡眠状态)
    – D(休眠状态/不可中断休眠状态)
    – 挂起状态
  • T(暂停状态)
    – 前台/后台进程
    – t(待追踪暂停状态)
  • X(死亡状态)
  • Z(僵尸状态)


就绪运行状态R

虽然从字面理解,运行状态就是进程在CPU上运行,但并非如此!
R(运行状态)代表进程在运行队列中排队,而队列的维护是操作系统来做的;可以理解为进程就绪,等待CPU资源的状态!

#include <iostream>
using namespace std;

int main()
{
   while(true); //死循环
   return 0;
}

test
在Linux系统中,新建、就绪、运行都可以看作运行 R 这一个状态,清晰明了!



阻塞

阻塞进程因为等待某种条件就绪,而导致的一种不推进状态,也就是进程卡住了;阻塞一定是在等待某种资源!
为什么会阻塞?进程要通过等待的方式,等具体的资源被别的进程用完之后,再被自己使用。

简而言之:阻塞就是进程等待某种资源(磁盘,网卡,显卡等各种外设)就绪的过程。

当一个进程运行到某指令时需要外部资源时,操作系统会将进程就会撤出CPU,放到某种资源处进行排队,也就不在CPU上运行了,直到该进程获取到了所有资源(具备运行条件),操作系统会将此进程放入运行队列中进行排队,继续运行!

综上:进程PCB可以被维护在不同的资源队列中; 所以阻塞就是不被调度,一定是因为当前进程需要等待某种资源就绪;在Linux系统下,一定是task_struct结构体需要在某种被操作系统管理的资源下排队!


睡眠状态 S

睡眠状态是可中断休眠,是阻塞的一种

当进程需要某资源时,操作系统将该进程挂到对应的资源队列排队,此时进程处于可中断休眠状态!

#include <iostream>
using namespace std;
>#include <unistd.h>

int main()
{
   while(true) //死循环打印pid
   {
       cout<<getpid()<<"进程运行中..."<<endl;
       sleep(1);
   }
   return 0;
}

可中断休眠
这里可能会有小伙伴疑惑,进程在运行,为什么不是显示R,而是S+?
这里需要说明一下的是,进程向屏幕不断打印的行为也是I/O行为,需要向屏幕这个硬件进行写入,所以每次申请写入屏幕时需要到对应资源队列排队并处于休眠状态,而CPU的运行速度非常快,在此过程中,进行几万次捕捉可能就只有一两次看到进程处于R状态,其他时候都是S+状态。

可能小伙伴还有一个问题,那么S+状态的 + 是什么意思?这个 + 的意思是代表该进程在前台运行,具有体前台后台进程的区别在暂停状态会简单介绍!

处于可中断休眠状态的进程可以被CTRL+C或kill -9等信号终止进程!
CTRL+C发送2号信号


休眠状态D

休眠状态是不可中断休眠状态,也是阻塞的一种!

休眠状态下的进程无法别终止,kill信号和操作系统都无法终止,只能等待进程获取到了对应的资源(达到对应条件)才能终止休眠状态; 当然,通过切断电源的方式也可以强制关闭,但是那样操作系统也关闭了,且会损失数据!

这种状态一般可能出现在,例如进程需要在磁盘上I/O,但是此时磁盘I/O阻塞了,此时如果影响进程可能会造成数据损坏,所以操作系统为了保证数据安全,不会插手这件事,一般很少会碰到该状态,如果碰到了该状态,那么计算机很可能就要崩溃了!

所以这种状态的出现往往是为了保护进程,但是最好尽量避免出现这种状态!


挂起

挂起一般又称阻塞挂起,也是一种特殊的阻塞状态!

当系统资源紧张,某些进程在运行时等待资源阻塞时,操作系统保留PCB转而释放该程序的代码和数据(放到硬盘上)腾出空间,此时进程被挂起。



暂停状态T

我们可以使用kill信号的方式让进程进入暂停状态;进入暂停状态的进程不在运行并保持在后台!

使进程暂停的方法:SIGCONT信号

  • kill -19 进程PID (暂停进程)
  • kill -18 进程PID (恢复进程)
    暂停状态T

前台与后台进程

在Linux系统下,当进程在前台运行时其状态会附带一个 +,代表该进程是前台进程!
如果是后台进程则没有 + 符号!
进程可以在不同的状态下处于前台和后台运行!
前台与后台


待追踪暂停状态t

该状态是指该进程正在被另一个进程跟踪,例如在Linux下通过GDB调试一个程序,GDB中对被跟踪的进程打一个断点,进程在断点处停下来的时候就处于 t 状态。而在其他时候,被跟踪的进程还是处于其他。对于进程本身来说,T 和 t 状态很类似,都是表示进程暂停下来。
gdb



死亡状态 X

当进程结束或被终止时进入死亡状态,这个状态只是一个返回状态,你不会在任务列表里看到这个状态。因为CPU的处理速度非常快,这只是一瞬间!



僵尸状态 Z

僵尸状态是一个与死亡状态相似的状态,通常来说僵尸状态给父进程所准备的!

僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵死(尸)进程。僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。

当父进程创建子进程后,子进程已经运行结束,父进程需要去接收子进程的退出结果(返回值)来判断子进程是否正常运行或运行结果是否正常,然后回收子进程!

所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态。

#include <iostream>
using namespace std;
#include <unistd.h>
#include <cstdlib>

int main()
{
   pid_t id = fork();
   if(id == 0)
   {
       int i = 10;
       while(i--)
       {
           cout<<"子进程运行中..."<<endl;
           sleep(1);
       }
       cout<<"子进程退出!"<<endl;
       exit(0);
   }
   int i = 20;
   while(i--)
   {
       cout<<"父进程运行中..."<<endl;
       sleep(1);
   }
   cout<<"父进程退出!"<<endl;
   return 0;
}

子进程僵尸状态
维护僵尸进程的意义是为了让父进程读退出码,但是僵尸进程也有以下等危害:

  • 进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态。
  • 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护。
  • 那一个父进程创建了很多子进程,就是不回收,就会造成内存资源的浪费;因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!
  • 既然进程一直在内存中保存,就可能存在内存泄漏,需要释放。

所以我们要避免子进程长时间处于僵尸状态,后面在进程控制中会讲解回收监视子进程的办法!


孤儿进程


当父进程先于子进程结束或终止时,子进程就成为孤儿进程!
在Linux系统中,孤儿进程由1号进程bash接管成为后台进程!
孤儿进程
为什么bash要接管这个孤儿进程?

  • 如果不接管那么子进程在结束后没有父进程回收,一直处于僵尸状态,造成内存泄漏,所以需要bash接管进行释放!

进程优先级


进程除了有不同的状态,还有优先级之分:

  • cpu资源分配的先后顺序,就是指进程的优先权(priority)。
  • 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
  • 还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。

CPU的资源是有限的,合理分配才能最大化效能!
Linux 给我们提供了修改 进程 优先级的权限,目的就是让我们对多任务运行进行合理处理,提高系统运行效率。


查看进程优先级

ps指令可以加上 -al 选项显示进程的其他信息!

ps -al | head -1 && ps -al | grep 进程名(程序名) | grep -v grep

进程优先级查看
关于PRI与NI值
– PRI是进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高。

PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:(新的PRI)=(旧的PRI)+nice

– NI是nice值,其表示进程可被执行的优先级的修正数值。

– 当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行所以,调整进程优先级,在Linux下,就是调整进程nice值。

nice其取值范围是-20至19,一共40个级别;当我们设置nice值时超过这个区间是无效的!

– 这里需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。可以理解nice值是进程优先级的修正修正数据。

– 优先级的修改行为并不是连续的,每次都是在最开始的基础上进行修改(默认为 80)。

– 调度器不允许存在 优先级失衡 的情况,因此优先级修改不能太激进。



修改进程优先级

进程优先级可以修改,但一般我们是不干预操作系统的调度的!

修改步骤:

  • top指令打开Linux任务管理器
  • 输入 r 进入NI值修改模式
  • 输入想修改NI值进程的PID
  • 最后输入NI值即可(范围-20~19)

步骤:
1
2
3
4
2
动图演示:进程优先级修改


最后

进程状态和进程优先级的知识到这里就介绍的差不多了,通过了解进程状态,知道进程的阻塞和和运行的原理;了解进程优先级,学习了修改进程的优先级影响调度机制,这些知识都在为后面进程控制的学习打下基础,后面我们还会介绍有关Linux的环境变量相关知识,敬请期待!

本次 <Linux进程状态及优先级> 就先介绍到这里啦,希望能够尽可能帮助到大家。

如果文章中有瑕疵,还请各位大佬细心点评和留言,我将立即修补错误,谢谢!
结尾

🌟其他文章阅读推荐🌟
Linux<进程初识> -CSDN博客
C++ <STL之string的使用> -CSDN博客
C++ <模板> -CSDN博客
C++ <内存管理> -CSDN博客
🌹欢迎读者多多浏览多多支持!🌹

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

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

相关文章

nginx(七十三)nginx与Location响应头细节探讨

一 nginx与Location响应头细节探讨 ① 重定向和Location回顾 多种重定向跳转方式的差异 nginx之absolute_redirect、server_name_in_redirect、port_in_redirect 共同控制Location响应头 ② STS响应头导致307重定向 "第一次访问 http://www.baidu.com" 观察…

基于Qt、C++的毕业设计课设数学绘图工具(平面图、图表、立体图绘制-附下载链接)

基于Qt、C的毕业设计课设数学绘图工具&#xff08;平面图、图表、立体图绘制&#xff09; 介绍 这是我的毕业设计&#xff0c;基于Qt Creator 4.11.1&#xff0c;c语言。 效果图如下 点我下载项目源码&#xff08;含打包软件&#xff09; 使用说明 1. 二维函数绘制 开始界面…

python 系列 07 - 基于easyocr的ocr识别

OCR,光学文字识别&#xff0c;对文本资料进行扫描&#xff0c;然后对图像文件进行分析处理&#xff0c;获取文字及版面信息的过程。本示例通过easyocr库来演示。easyocr是一个比较流行的库&#xff0c;支持超过80种语言。安装的时候注意会附带安装torch库&#xff08;一个深度学…

将ROS1和ROS2安装到同一个ubuntu系统中,ROS2安装??????????????

1. 本文测试环境: ubuntu:20.04,虚拟机 ROS1:noetic ROS2:foxy 2. 先说结论 ROS1 与 ROS2 共存,需要考虑三个问题: 1) 不同Ubuntu版本,有不同版本的ROS1和ROS2推荐,尽量不要任性地乱装; 2)ROS1和ROS2安装过程中,是否会出现文件“删改”的问题?目前使用下来,并…

拓扑排序详解(包含算法原理图解、算法实现过程详解、算法例题变式全面讲解等)

前置知识 有向无环图 在图论中&#xff0c;如果一个有向图无法从某个顶点出发经过若干条边回到该点&#xff0c;则这个图是一个有向无环图&#xff08;DAG图&#xff09;。 如图所示。 入度 对于一个有向图&#xff0c;若x点指向y点&#xff0c;则称x点为y点的入度。 出度…

Redis --- 多级缓存

一、什么是多级缓存 传统的缓存策略一般是请求到达Tomcat后&#xff0c;先查询Redis&#xff0c;如果未命中则查询数据库&#xff0c;如图&#xff1a; 存在下面的问题&#xff1a; 请求要经过Tomcat处理&#xff0c;Tomcat的性能成为整个系统的瓶颈Redis缓存失效时&#xff…

python每日一练:硬币划分(多方法详解)

文章目录 前言0、题目一、暴力总是不能解决问题的二、还能更暴力一点三、减少暴力思想四、引入先进思想总结 前言 这题挺有意思的&#xff0c;典型的背包组合问题&#xff0c;虽然没有要求各种组合方式&#xff0c;不过我们可以试试给出组合方式。当然这题不太可能用一行代码解…

STM32 从入门到精通系列讲解 - 总目录

&#x1f466; 作者介绍&#xff1a;Bazinga bingo&#xff0c;专注C语言应用硬核干货分享&#xff0c;潜心修炼&#xff0c;虚心学习&#xff0c;立志做嵌入式相关赛道的Top。 &#x1f4d5; 本文收录于《STM32开发》专栏&#xff0c;包含STM32内部模块介绍、片内资源开发、不…

如何使用bingChat(使用方法+遇到的问题+感受)

文章目录 前言一、如何使用Bing Chat1. 下载new Bing2.重新注册一个microsoft&#xff08;此步骤可略过&#xff0c;如有问题再操作此步骤&#xff09;3. 使用 Bing Chat 二、常见问题1.Chat mode is only available when you have access to the new Bing.2. 网页上没有“聊天…

leetcode 104——二叉树的最大深度

文章目录 题目详情方法一 万能的递归方法二 通过使用层序遍历的方式Java完整代码递归实现非递归实现——借助队列 题目详情 给定一个二叉树&#xff0c;找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 l…

yolov5图像识别voc转yolo代码解析

https://github.com/ultralytics/JSON2YOLO https://blog.csdn.net/qq_51831335/article/details/127237772 目标检测数据集标签转换COCO2VOC、YOLO2VOC、JSON2YOLO <annotation><folder>VOC2007</folder><filename>000001.jpg</filename><s…

x265码控分析

D和R的关系 高分辨率量化 均匀量化&#xff1a;量化区间 ‘ Δ k y k − y k − 1 ‘ \Delta_ky_k-y_{k-1} ‘Δk​yk​−yk−1​‘&#xff0c;近似为常数&#xff1b;p(x)为信源概率密度函数&#xff0c;且 ‘ Δ k ‘ \Delta_k ‘Δk​‘的大小相对于p(x)的变化率充分小&…

【模拟IC学习笔记】 反馈

反馈的作用&#xff1a;增益灵敏度降低 采用开环的方式实现一个精确的增益比较困难&#xff0c;但是可以实现高增益。 增益灵敏度衍生出来的另外两个特点 1、增加系统带宽。 2、改变输出阻抗&#xff0c;提高驱动能力。 反馈的作用&#xff1a;增加带宽 带宽的增加来源于…

对传递函数的零极点、频率响应、稳定性的理解

对传递函数的零极点、频率响应、稳定性的理解 零极点 从传递函数求零极点 令传递函数分子为0求出零点&#xff0c;令分母为0求出零点。 频率响应 单极点系统的频率响应 A v A v d c ∗ ( 1 / ( 1 s R C ) ) AvAv_dc*(1/(1sRC)) AvAvd​c∗(1/(1sRC))&#xff0c;系统的极…

python通过SSH管道访问ClickHouse

目录 前言什么是跳板机什么是SSH协议SSH管道访问ClickHouse参考文献 前言 因为新业务需要&#xff0c;数据都存储在阿里云服务器的ClickHouse数据库里&#xff0c;最近想取点数探索一下&#xff0c;于是下载了客户端工具DBeaver并成功连接ClickHouse&#xff0c;然后想通过pyt…

【前端面试题】这些js功能你一定要学会

大厂面试题分享 面试题库 前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 web前端面试题库 VS java后端面试题库大全 1.图片失败&#xff0c;重新加载 如果图片资源不存在&#xff0c;那可以设置图片失败的占位…

深度学习——A3C算法

A3C算法&#xff08;Asynchronous Advantage Actor-Critic&#xff09; DDPG算法之后&#xff0c;DeepMind对其改造&#xff0c;提出了效果更好的 Asynchronous Advantage Actor-Critic&#xff08;A3C&#xff09;算法&#xff08;论文是 Asynchronous Methods for Deep Rein…

【谷粒商城之远程调用和异步调用丢失请求头问题】

本笔记内容为尚硅谷谷粒商城远程调用和异步调用丢失请求头问题部分 目录 一、Feign远程调用丢失请求头 二、Feign异步调用丢失请求头问题 一、Feign远程调用丢失请求头 ​ ​ 问题&#xff1a; feign在远程调用之前要构造请求&#xff0c;调用了很多的拦截器。 浏览器发送请…

u01使用率100%报错归档满的问题

今天下午客户报数据库无法连接了&#xff0c;我也立刻登录查看 因为显示orcl1归档满了&#xff0c;我就登录查看磁盘组的空间&#xff0c;发现空间空余很多 就sqlpus登录了&#xff0c;发现u01使用率满了 [oracledb1 ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 …

《面试1v1》动态代理

我是 javapub&#xff0c;一名 Markdown 程序员从&#x1f468;‍&#x1f4bb;&#xff0c;八股文种子选手。 面试官&#xff1a; 那你能说一下反射和动态代理的关系吗&#xff1f; 候选人&#xff1a; 当然可以。动态代理是一种基于反射的机制&#xff0c;它可以在运行时动…