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

        前言:博主在之前的文章已经讲解了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.mzph.cn/pingmian/47903.shtml

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

相关文章

云原生系列 - Jenkins

Jenkins Jenkins,原名 Hudson,2011 年改为现在的名字。它是一个开源的实现持续集成的软件工具。 官方网站(英文):https://www.jenkins.io/ 官方网站(中文):https://www.jenkins.io…

【Linux】汇总TCP网络连接状态命令

输入命令: netstat -na | awk /^tcp/ {S[$NF]} END {for(a in S) print a, S[a]} 显示: 让我们逐步解析这个命令: netstat -na: netstat 是一个用于显示网络连接、路由表、接口统计等信息的命令。 -n 选项表示输出地址和端口以数字格式显示…

贝锐蒲公英远程运维方案:即装即用、无需专线,断网也可远程维护

目前,公路、隧道、桥梁、航道,甚至是施工现场和工业生产环境等,都采用了实时监测方案。 通过部署各类传感器和摄像头等设备,现场视频画面和控制单元(如PLC、工控机等)数据可以实时回传,用于集中…

AI批量剪辑,批量发布大模型矩阵系统搭建开发

目录 前言 一、AI矩阵系统功能 二、AI批量剪辑可以解决什么问题? 总结: 前言 基于ai生成或剪辑视频的原理,利用ai将原视频进行混剪,生成新的视频素材。ai会将剪辑好的视频加上标题,批量发布到各个自媒体账号上。这…

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

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

基于JAVA+SpringBoot+Vue+uniApp的校园日常作品商品分享小程序

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、SpringCloud、Layui、Echarts图表、Nodejs、爬…

STM32、Spring Boot、MQTT和React Native:智能停车管理系统的全栈开发详解(附代码示例)

1. 项目概述 随着城市化进程的加快,停车难已成为许多大中城市面临的普遍问题。为了提高停车效率,改善用户体验,本文设计并实现了一套智能停车管理系统。该系统利用STM32微控制器、各类传感器以及移动应用,实现了停车位实时监控、…

缓存弊处的体验:异常

缓存(cache),它是什么东西,有神马用,在学习内存的时候理解它作为一个存储器,来对接cpu和内存,来调节cpu与内存的速度不匹配的问题。 缓存,一个偶尔可以听到的专业名词,全…

文章八:并发性能优化技巧

目录 8.1 引言 并发性能优化的重要性 本文的内容结构 8.2 减少锁争用 减少锁争用的方法 使用局部变量和无锁算法的示例 使用局部变量 无锁算法 8.3 无锁算法 无锁算法的基本概念 常用的无锁数据结构和算法示例 无锁队列 无锁栈 8.4 并发性能测试 性能测试工具和…

IDEA的详细设置

《IDEA破解、配置、使用技巧与实战教程》系列文章目录 第一章 IDEA破解与HelloWorld的实战编写 第二章 IDEA的详细设置 第三章 IDEA的工程与模块管理 第四章 IDEA的常见代码模板的使用 第五章 IDEA中常用的快捷键 第六章 IDEA的断点调试(Debug) 第七章 …

Air780E/Air780EP/Air780EQ/Air201模块遇到死机问题如何分析

Air780E/Air780EP/Air780EQ/Air201模块遇到死机问题如何分析 简介 本文档适用于合宙Air780E、Air780EP、Air780EQ、Air201 关联文档和使用工具: 从Ramdump里分析内存泄漏问题 无法抓底层log的情况下如何导出死机dump Luatools下载调试工具 EPAT抓取底层日志 F…

npm install报错:npm error ERESOLVE could not resolve

从git上拉取一个新vue项目下来,在npm install时报错:npm error ERESOLVE could not resolve 有网友分析原因是因为依赖冲突导致报错,解决方法如下: # --legacy-peer-deps:安装时忽略所有peerDependencies&#xff0c…

Hadoop-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等

点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: HadoopHDFSMapReduceHiveFlumeSqoopZookeeperHBaseRedis 章节内容 上一节我们完成了: HBase …

组合数学+费用背包+刷表,G2 - Playlist for Polycarp (hard version)

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 G2 - Playlist for Polycarp (hard version) 二、解题报告 1、思路分析 一…

【flink】之如何快速搭建一个flink项目

1.通过命令快速生成一个flink项目 curl https://flink.apache.org/q/quickstart.sh | bash -s 1.19.1 生成文件目录: 其中pom文件包好我们所需要的基础flink相关依赖 2.测试 public class DataStreamJob {public static void main(String[] args) throws Except…

苍穹外卖(一)之环境搭建篇

Ngnix启动一闪而退 启动之前需要确保ngnix.exe的目录中没有中文字体,在conf目录下的nginx.conf文件查看ngnix的端口号,一般默认为80,若80端口被占用就会出现闪退现象。我们可以通过logs/error.log查看错误信息,错误信息如下&…

百日筑基第二十四天-23种设计模式-结构型总汇

百日筑基第二十四天-23种设计模式-结构型总汇 前言 设计模式可以说是对于七大设计原则的实现。 总体来说设计模式分为三大类: 创建型模式,共五种:单例模式、简单工厂模式、抽象工厂模式、建造者模式、原型模式。结构型模式,共…

SAPUI5基础知识16 - 深入理解MVC架构

1. 背景 经过一系列的练习,相信大家对于SAPUI5的应用程序已经有了直观的认识,我们在练习中介绍了视图、控制器、模型的概念和用法。在本篇博客中,让我们回顾总结下这些知识点,更深入地理解SAPUI5的MVC架构。 首先,让…

【AMD/Xilinx】FPGA远程烧录调试工具安装及使用

问题描述 在学习工作中,本人遇到了连接FPGA的服务器电脑没有Vivado或Vivado版本较低,导致没办法查看ila的情况。在这种情况下一方面重新安装Vivado需要占用大量存储空间,另一方面使用远程桌面软件连接服务器电脑的画质较为模糊,影…

保姆级教程!!教你通过【Pycharm远程】连接服务器运行项目代码

小罗碎碎念 这篇文章主要解决一个问题——我有服务器,但是不知道怎么拿来写代码,跑深度学习项目。确实,玩深度学习的成本比较高,无论是前期的学习成本,还是你需要具备的硬件成本,都是拦路虎。小罗没有办法…