Linux系统编程:进程的状态和进程优先级

news2025/1/15 13:08:58

目录

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

二. 进程状态的标识 

2.1 运行状态R

2.2 睡眠状态S

2.3 前台进程和后台进程

2.4 磁盘睡眠状态D

2.5 暂停状态和调试状态T

2.6 僵尸状态Z

2.7 终止状态X

2.8 孤儿进程 

三. 进程优先级

3.1 什么是优先级

3.2 进程优先级的修改和进程切换

四. 总结 


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

  • 就绪:新进程被创建出来,PCB加入到运行队列等待运行的进程。
  • 运行:进程正在使用CPU资源运行的状态。
  • 阻塞:进程等待非CPU资源就绪的状态,如:文件的读写需要等待磁盘资源就绪。

操作系统中一定存在着各种资源,不仅仅是CPU,如磁盘、显卡、网卡等,都属于操作系统的资源。同时,操作系统中不仅仅有运行队列,还有阻塞队列。如图1.1所示,假设运行队列队头的进程A正在占用CPU资源,而某一时刻进程A需要从磁盘上读取数据,然而此时磁盘资源尚未就绪,这是进程A就会被添加到磁盘的阻塞队列去等待相关磁盘资源的就绪。当磁盘资源就绪后,进程A就会被再次加入到运行队列等待CPU运行。进程A在等待磁盘资源就绪的过程中,它的状态就是阻塞状态。

图1.1 运行队列和阻塞队列
  • 挂起状态:当开启的进程过多,内存资源几乎饱和使用的情况下,操作系统会将尝试见不允许的进程的代码和数据置换到磁盘的一块区域(注意进程的PCB不会被置换出去),被置换的进程的状态叫做挂起。

磁盘中有一块分区专门用于进行置换,在Windows下为pagefile.sys虚拟内存,在Linux/Centos下为Swap分区。

图1.2 进程的挂起
图1.3 进程状态之间的切换

二. 进程状态的标识 

2.1 运行状态R

写一段while(1)死循环代码,循环体内不进行任何工作,编译生成可执行文件并运行,另开终端使用ps指令查看进程状态,可见进程状态为R+,即为运行状态进程。

int main()
{
    while(1)
    {  }
    return 0;                                                                                                              
}
图2.1 运行状态进程

2.2 睡眠状态S

阻塞状态就是等待CPU资源就绪的状态,在代码死循环while(1)中不断使用printf向显示屏输出数据,通过脚本命令,间隔1s输出进程信息,可以看见进程状态为S+,即阻塞状态。

int main()    
{    
    while(1)    
    {    
        printf("hello world\n");    
        sleep(1);                                                                                    
    }      
    return 0;    
}  

这里基本上不会显示R状态,因为CPU的速度要远高于外部设备,且差别为数量级级别,导致程序运行期间99.99%以上的时间都在等待非CPU资源,所有我们观察到的进程状态一直为S+。

图2.2 睡眠状态S进程

S睡眠状态的进程,可以强制中断睡眠。 睡眠状态,类似于阻塞状态。

2.3 前台进程和后台进程

我们注意到,2.1和2.2在查看进程状态时,都看到了R和S后面的+,+表明该进程是前台进程,后台进程不会有+,起点后台进程需要&符号做标识。

  • 后台启动进程的语法:./XXX &

在后台启动2.2中程序的进程,监测进程状态,发现进程状态变为了S而非S+。

图2.3 后台进程

通过Ctrl + C无法强制终止后台进程的运行,需要通过9号信号终止。

  • 后台进程终止命令:kill -9 进程pid 

2.4 磁盘睡眠状态D

磁盘睡眠状态,可认为是一种深度睡眠状态,不能强制中断睡眠。如果D状态的睡眠被强制中断了,那么就会存在不可知的风险。

举个例子,假设某个进程在往磁盘中写数据,我们通过Ctrl+C或其他手段,企图强制终止睡眠,这种操作时不被运行的。因为如果进程还没写完就强制终止掉它,那么就无法给进程返回信息,确定文件读写是否成功,也有可能造成文件内容不全的问题。

通过dd指令,可以对D状态进程进行模拟。dd的功能为将一个文件的内容拷贝到另一个文件。

  • dd的语法:dd if=输入文件名 of=输出文件名 bs=每块的大小 count=读取块数

输入和输出文件名在缺省时,为标准输入和输出。

图2.4 使用dd指令模拟磁盘睡眠状态

2.5 暂停状态和调试状态T

写一段死循环代码,生成可执行程序myproc并运行,先通过ps指令查看进程pid,此时向进程发送19号暂停信号(SIGSTOP),此时输出进程属性信息,状态为T,再向进程发送18号继续运行信号(SIGCONT),此时进程状态变为S。

打开gdb调试程序程序,也能检测到T状态。

图2.5 暂停状态进程

2.6 僵尸状态Z

  • 是什么:一个进程已经退出,但是操作系统还不允许释放这个进程的资源,处于被检测的状态,此时这个进程就是僵尸状态进程。一般由父进程或操作系统进行检测。
  • 为什么:子进程已经终止,但是父进程还在运行并且没有对子进程进行处理,那么这个子进程就处于僵尸状态。

编写如下所示的代码,通过fork创建子进程,在父子进程内死循环打印pid和ppid,通过9号信号终止子进程,检测进程属性信息,此时子进程状态为Z。

#include<iostream>    
#include<unistd.h>    
#include<stdlib.h>    
    
int main()    
{    
    pid_t ret=fork(); //创建子进程    
    
    if(ret < 0)  //进程创建失败    
    {    
        perror("fork");    
        return 1;    
    }    
    else if(ret == 0)  //子进程代码    
    {    
        while(1)    
        {    
            printf("Child Process, pid:%d, ppid:%d\n", getpid(), getppid());    
            sleep(1);    
        }    
    }    
    else  //父进程代码    
    {    
    
        while(1)    
        {    
            printf("Parent Process, pid:%d, ppid:%d\n", getpid(), getppid());                        
            sleep(1);    
        }    
    }    
    
    return 0;    
}  
图2.6 僵尸状态进程

僵尸进程的危害:

  • 如果父进程一直不读取子进程状态,那么子进程就一直处于僵尸Z状态,操作系统就必须一直维护这样的僵尸状态。同时,僵尸状态的PCB必须一直被操作系统内置的数据结构和算法维护,会造成资源浪费。
  • 僵尸进程会造成内存泄漏问题。

2.7 终止状态X

如果一个进程已经终止,但是操作系统还没来得及回收资源,那么这个进程就处于终止X状态。

2.8 孤儿进程 

概念:如果一个进程的父进程终止了,但是这个进程(子进程)本身还在运行,那么这个进程就是孤儿进程。

处理方法:孤儿进程会被1号进程init领养。

下面的代码通过fork创建父子进程,父进程循环5次后退出,子进程不断运行,通过监测,我们发现,一开始子进程的ppid为其最开始父进程的pid,但后面变为了1,表明子进程在父进程终止后变为了孤儿进程,被1号进程收养。

#include<iostream>    
#include<unistd.h>    
#include<stdlib.h>    
    
int main()    
{    
    pid_t ret=fork(); //创建子进程    
    
    if(ret < 0)  //进程创建失败    
    {    
        perror("fork");    
        return 1;    
    }    
    else if(ret == 0)  //子进程代码    
    {    
        while(1)    
        {    
            printf("Child Process, pid:%d, ppid:%d\n", getpid(), getppid());    
            sleep(1);    
        }    
    }    
    else  //父进程代码    
    {    
        int cnt = 5;    
        while(cnt--)                                                                                 
        {    
            printf("Parent Process, pid:%d, ppid:%d\n", getpid(), getppid());    
            sleep(1);    
        }    
    }    
    
    return 0;    
}  
图2.7 孤儿进程

三. 进程优先级

3.1 什么是优先级

  • 优先级的概念:就是进程PCB中的一个属性参数,用来表示进程占用CPU资源的先后顺序,确定谁先获得CPU资源,谁后获得。
  • 为什么存在优先级:因为CPU资源是有限的,进程需要通过某种方式竞争CPU资源。
  • 优先级是调度器确定进程运行顺序的重要依据。

某一个进程的优先级,可以表示为:老的优先级 + nice值。即:PRI(new) = PRI(old) + NI

查看进程全部信息指令(包括优先级):ps -al

图3.1 进程优先级信息

3.2 进程优先级的修改和进程切换

  • 方法:top指令打开任务管理器 -> 输入r,输入要进行修改的进程的pid -> 输入新的nice值
  • 优先级的数值越低,表示优先级越高,越先享用CPU资源。nice值为正数,表示降低进程优先级,nice为负数,表示提高进程优先级。
  • 默认的PRI为80,NI为0。如果要将NI改为负数,需要管理员权限。

关于进程的切换,有以下概念和注意事项:

  • 进程具有独立性,每个进程独占CPU资源,它们之间互不干扰。独立性包括父子进程,父进程和子进程之间也是独立的。
  • 时间片:CPU并不是要将一个进程的代码全部运行结束后,才去运行下一个进程,而是给每个进程设置特定的时间片,时间片到了之后,就让出CPU资源,到运行队列中排队等待下一次运行。
  • 抢占:高优先级进程抢占低优先级进程的CPU资源,即使低优先级进程的时间片还没到。
  • 出让:某个进程在时间片还没到时,就因为各种原因,让出了它所占用的CPU资源。
  • 假设进程A正在被CPU运行,那么CPU的寄存器中必须存储进程A的上下文信息,以便于确定进程A具体执行到了什么位置。当进程A的时间片结束,或者出让了CPU资源,那么要将进程A的上下文信息一并从CPU的寄存器中带走,以便下次运行进程A的时候能够继续之前的运行。

四. 总结 

  • Linux进程状态可以分为就绪、运行、阻塞、挂起等状态,就绪就是进程在运行队列中等待CPU执行,运行就是某个进程正在占用CPU资源运行,阻塞就是进程正在阻塞队列中等待非CPU资源,挂起就是内存资源接近饱和的时候,将某个进程的代码和数据暂时移动到磁盘中的状态。
  • 进程的状态可以细分为运行状态R、睡眠状态S、磁盘睡眠状态D、僵尸状态Z、暂停和调试状态T、死亡状态D、孤儿进程。进程还分为前台进程和后台进程。睡眠状态S可以被强制中断,磁盘睡眠状态不能被强制中断。
  • 进程的优先级用于调度器确定进程占用CPU资源的先后顺序,表示为PRI(new) = PRI(old) + NI。

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

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

相关文章

一文带你了解Java的I O机制

Java I/O 一&#xff1a;故事背景二&#xff1a;什么是Java的I\O机制2.1 流2.1.2 字节流和字符流的区别2.1.3 输入流和输出流的区别 2.2 文件 I/O2.3 缓冲 I/O2.4 标准 输入/输出2.5 对象序列化与反序列化2.6 N I/O 三&#xff1a;画图表示Java I/O机制3.1 输入输入系统流程示意…

vue中响应式的数组方法

vue响应式的数组方法 1、push 在数组中追加元素 <div id"app"><ul><li v-for"item in arr">{{item}}</li></ul><button click "change">按钮</button> </div> <script src"js/vue.js&…

普通单目相机标定——准备工作

前言 这里我们还是以普通相机为例(非鱼眼相机)来进行后续的相关标定操作,再回顾下相机的成像模型如下所示。 已知相机内参(fx,fy,u0,v0),畸变系数[k1,k2,k3,p1,p2],相机外参[R|T]。世界坐标系中点Pw(Xw,Yw,Zw),投影至像素坐标系点p(u,v)的计算过程如下。 1)由世…

Linux基础_1

目录 一、用户登录 1、root用户 2、普通&#xff08;非特权&#xff09;用户 二、终端terminal 1、终端类型 2、查看当前的终端设备 三、交互式接口 1、概念&#xff1a;启动终端后&#xff0c;在终端设备附加一个交互式应用程序 2、类型 3、什么是Shell 4、各种She…

Python源码:用turtle画美国队长盾牌

解析&#xff1a; 美国队长盾牌结构分析&#xff1a; 有4个圆和一个五角星组成。 源码如下&#xff1a; import turtle as t #控制画笔的速度 t.speed(10) #画最外面的大圆 t.penup() t.goto(100,-235) t.pendown() t.color("red","red") t.begin_fill(…

iOS 实现多scheme 切换环境完整流程

文章目录 一、 添加configuration二、 添加scheme三、 设置scheme 和 configuration的对应关系四 、 本地配置文件五、 运行 前言 我们在开发中都要涉及到切换环境&#xff0c;很多小伙伴是通过宏定义的方式实现 切换环境的 &#xff0c; 这种方式不优雅&#xff0c;还可造成每…

MySQL基础篇(day02,复习自用)

MySQL第二天 基本的SELECT语句大小规范注释命名规则数据导入指令select语句练习 运算符代码练习 基本的SELECT语句 SQL 可以写在一行或者多行。为了提高可读性&#xff0c;各子句分行写&#xff0c;必要时使用缩进 每条命令以 ; 或 \g 或 \G 结束 关键字不能被缩写也不能分行 关…

中国开源,迈入“新生代”

提到中国开源&#xff0c;大家会想到什么&#xff1f; “追随者&#xff0c;而不是创造者”“国外一开源&#xff0c;国內就自主”“全球开源社区里的nobody”……如果你带着这些“刻板印象”&#xff0c;参加近两年国內的开源活动&#xff0c;极大可能会受到不小的震撼。 中国…

cglib动态代理 | 如何生成代理类、代理类内容解析

文章目录 简介一、cglib动态代理有什么特点CgLib动态代理&#xff1a;优点&#xff1a;缺点&#xff1a; 二、Cglib如何生成代理类生成代理类的具体代码&#xff1a;生成代理对象的具体代码&#xff1a; 三、代理类内容解析持久化代理类&#xff1a;代理类内容&#xff1a; Cgl…

数据指标体系建设

一、什么是数据指标体系&#xff1f; 指标体系是从不同维度梳理业务&#xff0c;把指标有系统的组织起来。简而言之&#xff0c;指标体系指标体系&#xff0c;所以一个指标不能叫指标体系&#xff0c;几个毫无关系的指标也不叫指标体系。指标体系就像是一个整体、一辆车&#…

MacOS Sonoma 14.0 (23A5276g) Beta2 带 OC 引导双分区黑苹果镜像

苹果今日向 Mac 电脑用户推送了 macOS 14 开发者预览版 Beta2 更新&#xff08;内部版本号&#xff1a;23A5276g&#xff09;&#xff0c;本次更新距离上次发布隔了 15 天。 镜像下载&#xff1a; 微信公众号&#xff1a; macOS Sonoma 14.0 (23A5276g) Beta2 带 OC 引导双分…

【人工智能】— 深度神经网络、卷积神经网络(CNN)、多卷积核、全连接、池化

【人工智能】— 深度神经网络、卷积神经网络&#xff08;CNN&#xff09;、多卷积核、全连接、池化 深度神经网络训练训练深度神经网络参数共享 卷积神经网络&#xff08;CNN&#xff09;卷积多卷积核卷积全连接最大池化卷积池化拉平向量激活函数优化小结 深度神经网络训练 Pr…

罗大佑、把午睡打造成领域驱动设计创新-UMLChina建模知识竞赛第4赛季第6轮

DDD领域驱动设计批评文集 欢迎加入“软件方法建模师”群 《软件方法》各章合集 参考潘加宇在《软件方法》和UMLChina公众号文章中发表的内容作答。在本文下留言回答。 只要最先答对前3题&#xff0c;即可获得本轮优胜。第4题为附加题&#xff0c;对错不影响优胜者的判定&am…

最优化系列 之 线性规划问题的灵敏度分析(1/6)

一、实验目的&#xff1a; 1. 掌握用MATLAB、LINGO 、EXCEL优化工具箱解线性规划的方法&#xff1b; 2. 练习建立实际问题的线性规划模型&#xff1b; 3. 掌握线性规划灵敏度分析原理&#xff1b; 4. 预习线性规划的灵敏度分析原理及方法。 二、实验内容 题目1&#xff1a;求解…

【spring cloud学习】2、Eureka服务注册与发现

前言 一套微服务架构的系统由很多单一职责的服务单元组成&#xff0c;而每个服务单元又有众多运行实例。由于各服务单元颗粒度较小、数量众多&#xff0c;相互之间呈现网状依赖关系&#xff0c;因此需要服务注册中心来统一管理微服务实例&#xff0c;维护各服务实例的健康状态…

终端基础知识

CLI、Terminal、Shell、Prompt 一、CLI CLI is the abbreviation of Command Line Interface. It’s a text-based way of interacting with a computer. 相比于图像界面提供的按钮&#xff0c;你可以使用一行命令来实现你想要的功能&#xff0c;比如说打开、关闭文件&…

Linux用户信息关键文件详解

passwd文件说明 /etc/passwd文件记录了Linux所有用户的信息&#xff0c;是系统的关键文件之一。 文件格式内容如上图。 文件中的条目以“:”为分隔符&#xff0c;各个字段记录的信息依次为&#xff1a; 第一个字段&#xff1a;记录用户名 第二个字段&#xff1a;值x表示该用…

如何做一份干净的git提交记录

背景 毕业工作有一些年头了&#xff0c;之前在写工作代码或者给开源项目贡献的时候&#xff0c;提交代码都不是很规范&#xff0c;甚至可以说十分的随意&#xff0c;想到什么就提交什么&#xff0c;根本没有管理提交记录的概念或者想法&#xff08;当你身边的人都不怎么在意的…

基于SpringBoot+SpringCloud+vue的智慧养老平台设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

大数据企业开发全套流程

大数据企业开发基础流程 Linux命令 1 Hadoop(HDFSYarn)单机版环境搭建 Hadoop 是一个开源的分布式计算框架&#xff0c;由 HDFS&#xff08;Hadoop Distributed File System&#xff09;和 YARN&#xff08;Yet Another Resource Negotiator&#xff09;两个核心组件组成。HD…