linux进程——状态——linux与一般操作系统的状态

news2024/9/16 18:17:36

        前言:博主在之前的文章已经讲解了PCB里面的pid——主要讲解了父子进程PID, 以及fork的相关内容。 本节进入PCB的下一个成员——状态, 状态是用来表示一个进程在内存中的状态的, 进程在内存中肯能处于各种状态, 比如运行, 阻塞等等。本节将从一般的操作系统的传统概念开始讲起, 然后再讲解linux是如何维护状态的。

        ps:本节内容不好理解——linux的知识点都不太好理解, 建议了解进程的PCB的友友们进行观看。

进程状态的概念

        对于进程的状态, 我们首先要知道为什么要有进程的状态。就比如我们运行一个程序, 这个程序里面有一个scanf, 需要运行输入, 但是如果当需要输入到时候我们没有输入, 一直不管这个程序。 那么这个程序是不是就会一直在那里停着。 ——这个时候程序在运行吗?答案是一定没有运行。 程序这个时候没有被cpu计算, 所以就不算是运行状态, 而是其他等待或者闲置的状态。

        也就是说, 一个进程就要有各种各样的状态!

操作系统学科进程状态的概念

运行

        比如说在操作系统当中, 系统刚把我们的进程创建出来, 也就是PCB, 代码和数据创建出来。 这个状态就叫做新建状态。 不用的时候, 这个时候代码和数据已经执行完了, 这个就叫做终止状态。而正在被调度, 运行的程序就叫做运行状态。

        现在看下面一张图:

        我们知道, 操作系统对于进程的管理其实就是对于数据结构的管理, 只要拿到双链表里面的head。 那么就能对任何一个进程进行相应的增删查改运算。 

        但是, 我们要知道, 对于一个进程来说, 想要运行, 那么就需要加载到cpu中, 那么就要占用cpu的空间。而cpu说白了, 空间大小的量级是寄存器级别, 并且进程是非常多, 那么这些进程之间就势必是竞争的关系。 

        而为什么这些进程能够稳定有序的运行, 是因为cpu维护着一个runqueue,这个runqueue就叫运行队列。 

struct runqueue
{
    //运行队列
    struct task_struct* head;
    struct task_struct* tail;
    ……;
}

        运行队列里面有着各种各样的属性, 但是最重要的就是上面两个维护链表首尾的指针。 

        这两个指针的目的就是为了将task_struct链入队列之中, 更加方便维护我们的链表!所以, 这个队列维护的不是进程的代码和数据, 而是task_struct, 这个就是进程在cpu里面排队, 这个队列就叫做运行队列。 

        而调度器就是拿运行队列里面的进程, 进行相应的调度。 

        所有处于这个运行队列的进程就叫做运行态, 简称R状态。为什么说在运行队列里面的就是运行态?因为在运行队列里面的进程, 随时可以被cpu调度, 这些进程就相当于说——我已经准备好了!可以随时被调用!        

进程切换

        一个运行中的程序, 如果被cpu执行了, 是不是必须要执行完毕才能把自己从cpu上放下来?——不是!

        就比如我现在正在使用写这篇博客, 但是我可以直接将页面叉掉。 这个就相当于没有执行完就把程序从cpu上放下来了!

        而cpu之所以能够让每一个进程不必执行完才下来, 就有了一个时间片的概念——所谓的时间片, 其实就是int time_space之类的一个整形的数据。 这里面保存了一个时间, 比如说10ms, 那么对于一个进程来说, 他每一次被调度到cpu中执行, 都只会运行10ms, 然后就会放到运行队列的尾部等待下一次的调度。 也就是说, 因为时间片很短, 所以对于1s来说, cpu就可以调度很多次进程。 给我们的感觉就是每一个进程都在被调用!!!就比如我们有5个进程, 然后1ms, 就可以每个进程都被调用20次, 所以就给了我们这5个进程都在被执行的假象

        上面的1s其实就是一个时间段, 所以我们通常将这种在一个时间段内, 所有进程都会被执行的现象叫做并发执行!

        上面的操作本质上就是把进程从cpu上拿下来, 或者把进程从运行队列拿到cpu上面去。 这种操作, 就叫做进程切换。 

阻塞

什么是阻塞, 首先, 我们回顾一下操作系统, 下面是一个操作系统。 

        上面是一个进程正在等待的情况,具体情况读图 。未来我们可能有各种各样的数据, 这些数据可能不止关系到键盘, 而是各种硬件设备, 那么这个时候的情况就是这些硬件的结构体都拿出一个指针连接到这些PCB的上面,然后这些PCB再相互连接。 也就是说, 管理的硬件数据结构里面的head其实就是一个个waitqueue, 当一个设备没有就绪的时候就等待。 就绪了然后就被调度放到cpu中执行。 

        并且, 我们把这种在等待队列中等待设备就绪的过程——这个过程就是假如设备里没有数据。 那么这个进程就在等待,而当设备里有数据, 那么我们就可以直接把进程放到运行队列里的cpu中执行, 再读取设备中的数据——而其中等待的过程就称之为该进程处于阻塞状态!!

挂起

假如这个时候有两个设备, 一个是键盘, 一个是磁盘。 这个时候我们有一个进程正在处于阻塞状态!——键盘等待队列等待键盘输入。 但是这个时候如果再来了几个进程, 而这个时候操作系统的内存严重不足了!这个时候, 操作系统就要在保持正常的情况下, 省出来内存资源。 而我们知道一个进程如果在阻塞状态, 那么它的代码和数据就是处于一个空闲的状态。 这个时候操作系统就会将进程的PCB保留, 而进程的代码和数据就会被放到外设当中!

        当下次资源就绪的时候,进程就会被重新唤醒。 那么这个时候代码和数据再次从磁盘放到内存中!而这个过程就叫做换出和换入。 而换出后, 也就是代码和数据在磁盘时, 就叫做挂起状态!!!(这种挂起称为阻塞挂起)

linux下的状态——linux如何维护状态

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

接下来, 将一个一个对结构体里面的状态进行解释。

R状态——运行状态

        首先, 我们想要查看R状态, 要如何查看呢?

        我在这里先定义一个函数:

        上面的这个程序运行起来后, 会一直无限打印printf。 但是当我们使用ps加过滤的时候, 看到的进程状态其实是S, 而不是R, S代表睡眠, 相当于阻塞状态。 为什么会这样呢? 因为运行一个程序, 当我们打印的时候, 我们是向外设打印, 而外设是需要等待资源的。 所以我们的程序就需要很长的等待时间, 也就是下面的S, 睡眠状态。       

        但是, 如果我们将printf去掉, 那么就不用打印到外设上, 就不需要等待。 我们再查看进程状态, 进程的状态就是R运行了。 

        这里的运行状态R之后有一个加号, 这个加号代表前台运行, 也就是在命令行解释器运行。 这个时候我们如果再运行其他指令, 那么也是运行不了的。

        就像如图这样, 无论是什么指令都是没有办法运行的。 想要退出程序就是cral + C, 如果去掉加号就是R, 这个意思是后台运行。 这个运行不影响bash命令行。 用法就是./程序 & 

想要将这个程序退出就只能使用kill -9杀掉程序。

        

S状态——阻塞状态

我们都知道S状态就相当于阻塞状态, 那么如何理解, S状态相当于阻塞状态呢?

        首先我们知道, 阻塞状态其实就是我们的进程等待外设获取资源的时候, 这个过程进程是闲置的状态。 这个过程是阻塞。 那么请问, 我们将数据输入到外设的时候, 算不算外设等待输入的时候。 要知道, cpu的时间和外设的时间差距是非常大的。 cpu的时间量级是纳秒级别, 而外设的时间量级是毫秒级别, 两者相差了10的三次方。 所以当输入的时候, 消耗的时间对于CPU来说也是非常大的。 所以这个时间也算是等待输入, 那么回到我们上面的那个打印printf的程序中, 为什么程序明明在运行, 状态却是S呢? 本质的原因就是cpu计算太快了, 而打印太慢了, 导致这个我们查看程序状态的时候一直是S也就是阻塞状态。 

        所以, 归根结底, 向外设打印信息, 从外部读取数据, 归根结底没有区别, 对于CPU来说开销都很大, 都会使程序变成S状态。

D状态——深度睡眠

        D状态, 即disk Sleep, 磁盘睡眠也叫做深度睡眠。 也是一种阻塞状态。 那么, 既然它叫做深度睡眠, 是不是还有浅度睡眠呢? ——是的, S就叫做浅度睡眠。 那么我们如何理解深度睡眠呢? ——深度睡眠其实就是一种不响应操作系统任何请求的状态。 一般的阻塞状态, 当进程停止等待外设后就会进入运行状态, 但是深度睡眠只有当完成了特定的任务, 否则不会响应操作系统的任何命令, 即便系统关机了, 这个进程仍然会自己跑。 

        D状态状态的产生是因为向磁盘中写入数据:

        加入这个进程是一个有着很重要数据的进程, 某一天, 这个数据想要将1G数据写到磁盘中。 

        但是对于磁盘来说, 磁盘写入数据是有可能失败的。 虽然几率不大, 但是有可能使其他原因, 或者磁盘满了的原因导致写入失败。 所以对于进程来说, 他写入数据就不能将数据交给磁盘后不管了, 他要等待磁盘写入的结果。 如果没有写入成功, 可以再写入一次, 或者写入不成功后想其他办法处理数据。 

        那么进程就将数据交给磁盘了。 要知道, 内存的时间量级和磁盘的时间量级是相差了10的三次方, 差距很大。 所以, 对于进程来说, 这个等待时间是非常长的, 那么这个时候内存满了, 操作系统管理内存, 就势必要杀掉一部分进程——这个过程是必须等, 事实上, 我们使用电脑或者手机都遇到过打开一个程序, 然后闪退的情况, 这个的本质就是被进程给杀掉了。 这个时候这个进程因为等待磁盘, 会处于闲置的状态, 那么就容易被操作系统杀掉。 而被操作系统杀掉后, 磁盘就不会找不到进程, 那么他就不会在进程写入数据了。 这些数据丢了, 而如果数据很重要, 那么丢掉数据就会出现非常严重的后果。 所以, 为了避免这种情况, 就出现了深度睡眠——D状态。

        进程在交给磁盘写入数据时是不受操作系统管理的, 就是进入了深度睡眠, D状态。 相当于有一个免死金牌, 操作系统想要杀掉进程的时候, 这个进程就可以亮出免死金牌。 就可以不受操作系统的约束, 即便操作系统关机, 只要电源存在, 就可以一直进行写入。

        但是一般深度睡眠状态, 也就是进程向磁盘写入数据都是很短暂的。 如果时间很长, 以至于用户可以体会到的话, 这个时候操作系统基本就挂掉了。

T、t状态——暂停状态

对于T和t状态, 都叫做暂停状态。 我们可以使用kill -l查看暂停的指令。 

如上图:19是暂停业务, 18是继续业务。 使用如下:

19是暂停进程, 如下图:

此时的运行状态时T, 如下, 就代表暂停(加号代表前台)

18是继续如下图:

此时的进程状态是S, 睡眠:

以上是本节内容, 后续会有僵尸进程的讲解补充。 下面是本节内容的笔记:

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

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

相关文章

十七、【机器学习】【非监督学习】- K-均值 (K-Means)

系列文章目录 第一章 【机器学习】初识机器学习 第二章 【机器学习】【监督学习】- 逻辑回归算法 (Logistic Regression) 第三章 【机器学习】【监督学习】- 支持向量机 (SVM) 第四章【机器学习】【监督学习】- K-近邻算法 (K-NN) 第五章【机器学习】【监督学习】- 决策树…

前端Vue组件化实践:自定义发送短信验证码弹框组件

在前端开发中,随着业务逻辑的日益复杂和交互需求的不断增长,传统的整体式开发方式逐渐暴露出效率低下、维护困难等问题。为了解决这些问题,组件化开发成为了一种流行的解决方案。通过组件化,我们可以将复杂的系统拆分成多个独立的…

使用 OpenCV 和 YOLO 模型进行实时目标检测并在视频流中显示检测结果

文章目录 Github官网简介视频帧推理视频设备ID安装依赖 检测示例分类示例姿势估计 Github https://github.com/ultralytics/ultralytics 官网 https://docs.ultralytics.com/zhhttps://docs.ultralytics.com/zh/quickstart/ 简介 Ultralytics 是一个软件公司,专…

深入浅出WebRTC—NACK

WebRTC 中的 NACK(Negative Acknowledgment)机制是实时通信中处理网络丢包的关键组件。网络丢包是常见的现象,尤其是在无线网络或不稳定连接中。NACK 机制旨在通过请求重传丢失的数据包来减少这种影响,从而保持通信的连续性和质量…

【VUE】v-if和v-for的优先级

v-if和v-for v-if 用来显示和隐藏元素 flag为true时&#xff0c;dom元素会被删除达到隐藏效果 <div class"boxIf" v-if"flag"></div>v-for用来进行遍历&#xff0c;可以遍历数字对象数组&#xff0c;会将整个元素遍历指定次数 <!-- 遍…

《数据结构:C语言实现双链表》

文章目录 一、链表的分类二、双向链表1、概念与结构 三、双向链表实现1、双向链表要实现的功能2、哨兵位初始化3、双链表头插数据4、判断链表是否为空5、打印链表数据6、尾插数据7、头删数据8、尾删数据9、寻找数据所在结点10、在任意结点之后插入数据11、删除任意结点12、销毁…

debian 更新源

前言 实现一键替换在线源 一键更新源 Debian 全球镜像站以下支持现有debian 11 12 echo "Delete the default source" rm -rf /etc/apt/sources.listecho "Build a new source" cat <<EOF>>/etc/apt/sources.list.d/debian.sources Types:…

Shell的正确使用

目录 shell 介绍 变量名的定义规则 变量名定义&#xff1a; 删除变量 特殊的变量名&#xff1a; 算术运算符 逻辑运算符&#xff1a; (1)整数之间比较 (2)按照文件权限进行判断 (3)按照文件类型判断 (4)多条件判断 常用的特殊字符&#xff1a; 条件选择、判断 if判…

PHP上门按摩专业版防东郊到家系统源码小程序

&#x1f486;‍♀️【尊享级体验】上门按摩专业版&#xff0c;告别东郊到家&#xff0c;解锁全新放松秘籍&#xff01;&#x1f3e0;✨ &#x1f525;【开篇安利&#xff0c;告别传统束缚】&#x1f525; 亲们&#xff0c;是不是厌倦了忙碌生活中的疲惫感&#xff1f;想要享…

NET 语言识别,语音控制操作、语音播报

System.Speech. 》》System.Speech.Synthesis; 语音播报 》》System.Speech.Recognition 语音识别 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Speech.Recog…

[Redis]典型应用——分布式锁

什么是分布式锁&#xff1f; 在一个分布式系统中&#xff0c;也会涉及到多个节点访问同一个公共资源的情况。此时就需要通过锁来做互斥控制&#xff0c;避免出现类似于"线程安全"的问题 举个例子&#xff0c;在平时抢票时&#xff0c;多个用户可能会同时买票&#…

Linux——多路复用之poll

目录 前言 一、poll的认识 二、poll的接口 三、poll的使用 前言 前面我们学习了多路复用的select&#xff0c;知道多路复用的原理与select的使用方法&#xff0c;但是select也有许多缺点&#xff0c;导致他的效率不算高。今天我们来学习poll的使用&#xff0c;看看poll较于…

利用AI与数据分析优化招聘决策

一、引言 在竞争激烈的职场环境中&#xff0c;招聘是组织获取人才、实现战略目标的关键环节。然而&#xff0c;传统的招聘方式往往依赖人力资源部门的主观经验和直觉&#xff0c;难以准确预测招聘效果&#xff0c;评估招聘渠道的效率。随着人工智能&#xff08;AI&#xff09;…

Windows右键新建Markdown文件类型配置 | Typora | VSCode

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 今天毛毛张分享的是如何在右键的新建菜单中添加新建MarkdownFile文件&#xff0c;这是毛毛张分享的关于Typora软件的相关知识的第三期 文章目录 1.前言&#x1f3dd;…

Android车载MCU控制音量和ARM控制音量的区别和优缺点—TEF6686 FM/AM芯片

不要嫌前进的慢&#xff0c;只要一直在前进就好 文章目录 前言一、系统架构图1.MCU控制音量的架构图&#xff08;老方法&#xff09;2.ARM控制音量的架构图&#xff08;新方法&#xff09; 二、为啥控制音量不是用AudioManager而是执着去直接控制TDA7729&#xff1f;三、MCU控制…

[数据集][目标检测]婴儿车检测数据集VOC+YOLO格式1073张5类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1073 标注数量(xml文件个数)&#xff1a;1073 标注数量(txt文件个数)&#xff1a;1073 标注…

Matlab基础语法篇(下)

Matlab基础语法&#xff08;下&#xff09; 一、逻辑基础&#xff08;一&#xff09;逻辑运算符&#xff08;二&#xff09;all、any、find函数&#xff08;三&#xff09;练习 二、结构基础&#xff08;一&#xff09;条件结构&#xff08;1&#xff09;if-elseif-else-end&am…

通过albumentation对目标检测进行数据增强(简单直接)

albumentation官方文档看不懂&#xff1f;xml文件不知道如何操作&#xff1f;下面只需要修改部分代码即可上手使用 要使用这个方法之前需要按照albumentation这个库还有一些辅助库,自己看着来安装就行 pip install albumentation pip install opencv-python pip install json…

<数据集>蛋壳裂缝检测数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;2520张 标注数量(xml文件个数)&#xff1a;2520 标注数量(txt文件个数)&#xff1a;2520 标注类别数&#xff1a;2 标注类别名称&#xff1a;[crack, egg] 序号类别名称图片数框数1crack245128352egg25142514 使…

揭秘饲料制粒机:生产颗粒料加工的利器

随着现代畜牧业的发展&#xff0c;饲料的质量和加工效率成为了养殖业者关注的焦点。在这个背景下&#xff0c;饲料制粒机——这一饲料加工设备的核心&#xff0c;凭借其稳定、环保的特点&#xff0c;逐渐加入养殖行业中。 一、饲料制粒机的工作原理 饲料制粒机主要通过挤压、切…