进程的状态的理解(概念+Linux)

news2024/11/20 7:19:14

文章目录

  • 进程的状态
    • 并行和并发
      • 物理和逻辑
    • 时间片
    • 进程具有独立性
    • 等待的本质
      • 运行
      • 阻塞
      • 标记
      • 挂起等待
  • Linux下的进程状态
    • (一)运行状态(R - running)
    • (二)睡眠状态(S - sleeping)
    • (三)磁盘休眠状态(D - disk sleep)
    • (四)停止状态(T - stopped)
    • (五)僵死状态(Z - zombie)
    • (六)孤儿进程

进程的状态

为了弄清楚正在运行的进程是什么意思,我们需要先来了解进程的不同的状态代表着什么。在一个系统中进程可以有几个状态。但是在这之前我们要明确几个知识点来辅助我们进行理解。

并行和并发

并行(Parallelism)
定义:多个进程在多个CPU下分别、同时进行运行。

需要有多个CPU核心或者多个处理器来支持。例如,在一个具有四核CPU的计算机上,可以同时运行四个进程,每个进程在一个独立的CPU核心上运行,它们之间互不干扰,可以同时进行各自的任务处理。

并发(Concurrency)
定义:指多个进程在一个 CPU 下采用进程切换的方式,在一段时间之内,让多个进程都得以推进。

操作系统通过快速地在多个进程之间切换CPU的执行权来实现并发。例如,在一个单核CPU的计算机上,同时运行着多个程序,如浏览器、音乐播放器和文本编辑器等。操作系统会给每个进程分配一小段时间片,在这个时间片内进程可以执行一些指令,当时间片用完后,操作系统会暂停该进程,保存其当前的运行状态(上下文),然后切换到另一个进程执行,如此循环往复,给用户一种多个程序同时运行的感觉。(因为CPU切换和运行的速度非常快且时间片足够小用户体会不到就会给用户一种多个程序同时运行的感觉)

简单来说就是:
CPU执行进程代码,不是将一个代码执行完毕之后再开始执行下一个代码,而是给每一个进程预分配出一个时间片,基于时间片进行调度轮转(单个CPU下)

物理和逻辑

在这里想说一个小点,物理层面上是一个CPU调度轮转多个进程。而在逻辑上我们可以将并发理解成,假设4个进程并发在一个CPU上,那么我们就可以理解成一个CPU被分成4份来使用,就好比一个100分的CPU被分成4个25分的CPU。这种物理与逻辑上面的的不同是为了更方便来让我们理解计算机中抽象的概念,像是堆的物理上数组来存储,而逻辑结构是二叉树的特殊规则等。


时间片

在这里我们明确两种操作系统就可以:
分时操作系统:Linux/Windows民用级别的操作系统,用的都是分时操作系统。
实时操作系统:汽车的系统等。
至于原因,在我们日常生活中所用的操作系统我们会同时进行很多任务而这些任务有没有明确的优先级,所以为了调度任务的公平,让所有任务都流畅的推进,就采用分时操作系统。在汽车系统中,安全相关的功能如刹车辅助系统、防抱死系统等需要实时操作系统的支持。这些系统必须能够在极短的时间内对传感器检测到的危险信号做出反应,例如,当车辆的传感器检测到前方有障碍物需要紧急刹车时,刹车系统相关的进程必须立即获得 CPU 资源进行制动操作,而不能等待其他非关键任务(如音乐播放、导航等)的时间片结束(总不能CPU说等会等音乐的时间片过去的我再进行刹车系统( ̄▽ ̄)")。同时,在汽车系统中,一些非安全关键的功能如多媒体播放、导航等可以采用分时操作系统来运行,以充分利用系统资源,提高用户体验。

简单就是让大家更好的体会时间片这个概念。


进程具有独立性

进程的独立性是指在多进程运行环境下,每个进程都具有以下特点:
1. 资源独享
内存空间独立
每个进程都有自己独立的地址空间,这意味着一个进程无法直接访问另一个进程的内存区域。例如,进程 A 中的变量存储在其自身的虚拟地址空间内,进程 B 无法直接读取或修改这些变量的值。这种内存空间的独立性是通过操作系统的内存管理机制来实现的,操作系统会为每个进程分配一段独立的内存区域,并通过地址映射等技术将虚拟地址转换为物理地址,确保进程之间不会相互干扰。
其他资源独立
除了内存空间,进程在使用其他系统资源时也具有一定的独立性。例如,进程在使用文件资源时,每个进程都有自己的文件描述符表,用于记录该进程打开的文件信息。即使多个进程打开了同一个文件,它们对文件的操作也是相互独立的,各自维护自己的文件读写位置等信息。

2. 执行互不干扰
指令执行顺序独立
每个进程都按照自己的指令流顺序执行,不受其他进程的影响。例如,进程 A 可能正在执行一段循环代码,而进程 B 可能在执行一个文件读取操作,它们各自按照自己的程序逻辑推进,不会因为另一个进程的存在而改变自己的执行顺序。
时间片分配独立
在操作系统采用时间片轮转调度算法的情况下,每个进程获得的时间片是独立分配的。也就是说,进程 A 的执行时间片用完后,它会被暂停,等待下一次时间片分配,而这个过程与其他进程的时间片分配情况无关。


等待的本质

在操作系统中每一个CPU都有一个执行队列struct runqueuestruct runqueue里面包含队列属性其中有task struct *head,在进程的算法中当我们启动一个进程我们就把新创建的进程tack_struct链入到task struct *head中,当我们进程变多时会链接的越来越多,而CPU在运行的时候会直接找到struct runqueue根据FIFO的调度算法会选择进程的代码地址放到CPU的寄存器中进行执行,而执行完之后会将刚才执行的tack_struct链接到整个链表的尾部,这样循环往复就形成基于时间片进行轮转的FIFO的调度算法,如下图:
在这里插入图片描述

运行

那么什么是一个进程处于运行状态呢?
在之前我以为的是只有在CPU上运行的才是处于运行状态
通过上面的铺垫我们可以引出只要是在运行队列中的,这个进程就是处于运行状态,因为它已经是准备好的可以随时被CPU进行调度

阻塞

我们一般进程中我们的代码中大多数都会包含IO操作,eg:等待键盘数据,读文件等等。以scanf为例,在我们执行程序的时候到scanf时候但是我们并没有在键盘上输入任何数据的时候(这个时候我们叫键盘数据没有准备好,即用户没有按键盘),那么此时CPU就不能一直执行这个程序,所以这个程序就会进入阻塞状态中。

操作系统管理硬件和上面进程类似,都是先描述在组织,设计一个链表进行连接每个硬件,如图:
在这里插入图片描述
那么我的代码只有scanf,当我们调用的时候他的内部一定是会封装调用的(因为scanf的本质是访问键盘),而管理硬件的是操作系统,在整个的系统中只有操作系统最清楚硬件的状态,那么说白了scanf的封装就是让操作系统查键盘的状态,那么当键盘没有数据的时候我们的进程的状态就是阻塞。在类里面有一个等待队列task_struct *wait_queue就是说在查询硬件的状态的时候发现是没有数据的CPU就会将这个进程扔进等待队列,简单理解就是CPU将这个进程从运行队列扔到我们的设备struct device中等待
在这里插入图片描述
所以我们把在设备上的等待状态叫做阻塞状态
而在之后用户想通了终于输入了,操作系统就知道了就会把这个进程(键盘中第一个等待进程)从等待队列中取出再放到CPU上运行

标记

所以总结:
综上所述运行阻塞的本质就是将不同的进程处于不同的队列中
那么回到标题,阻塞最直观的表现就是等待,等待的本质就是:连入目标设备,CPU的不调度!

挂起等待

前提:当内存资源严重不足时!!!
在操作系统读取运行队列的task_struck的时候进入阻塞状态,那么这个进程被扔进struck device的等待队列中,但是在等待的期间你的这个进程根本不会被调度,但是你这个进程的PCB占用一点内存和你的代码和数据相比较更加占用内存,而在这个期间当内存资源严重不足时!!! 所以操作系统为了保证自己的正常运行(操作系统也是一个大的软件)想到的一个解决方案,那么在阻塞的进程即占用内存又不执行所以操作系统会选择这些 进程的代码和数据换出到磁盘当中 而当被换出的这个进程准备好之后操作系统不仅会把这个进程的PCB放到运行队列中(改变状态),还要把刚才换出的程序和数据换回来(换入)。而在磁盘中有一个区域是swap分区,用来存放换出的所有数据。
在这里插入图片描述

所以一个进程一旦进入阻塞状态并且还被换出到磁盘中,那么此时的状态就是挂起(严格来说应该是阻塞挂起状态)
1.所以阻塞挂起的目的就是内存严重不足时在阻塞这个状态的背景下,通过将内存挂起到外设上面,从而节省内存
2.更严重的时候还会有运行挂起,就是把运行队列挂起到外设,来缓解内存不足
3.我们从冯诺依曼体系可以知道内存的作用就是提升整机的速度,这样挂起磁盘和内存交换数据必然会影响整体运行速度,所以这是在用时间来换空间没有办法的办法

一般在正常的生产环境下swap的功能都会被禁掉,因为空间不够生产环境可以加(优化软件,或者加服务器),但是时间不行。一般机器在内存不足时候或者连挂起都解决不了的话为了保证操作系统正常运行会直接杀掉其他进程(软件战术性闪退)

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 * 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 - running)

运行状态并不意味着进程一定在实际运行中。它表明进程要么正在CPU上执行指令,要么在运行队列里等待被调度到CPU上执行。在Linux内核中,这是一个动态的状态,多个进程可能处于这个状态,但只有一个进程能在某个时刻真正占用CPU资源。

(二)睡眠状态(S - sleeping)

睡眠状态意味着进程在等待某个事件完成。这种睡眠有时候也叫做可中断睡眠(interruptible sleep)。例如,进程可能在等待用户输入、某个文件的读取完成或者网络数据的接收。当等待的事件发生时,进程会被唤醒,重新进入运行队列或者直接开始执行。

(三)磁盘休眠状态(D - disk sleep)

磁盘休眠状态有时候也叫不可中断睡眠状态(uninterruptible sleep)。处于这个状态的进程通常在等待I/O操作的结束,比如磁盘写入或读取操作。在此期间,进程不会被信号中断,直到I/O操作完成。这是为了确保磁盘操作的完整性和数据一致性。

(四)停止状态(T - stopped)

进程可以通过发送SIGSTOP信号进入停止状态。这个被暂停的进程可以通过发送SIGCONT信号让其继续运行。这种状态常用于调试目的或者当系统需要暂时停止某个进程的执行,但又不想终止它时。

(五)僵死状态(Z - zombie)

僵死状态是一个比较特殊的情况。当进程退出并且父进程没有读取到子进程退出的返回代码时,就会产生僵死(尸)进程。僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。僵死进程会占用系统资源,因为相关的数据结构仍然需要维护在内存中,如果大量产生僵死进程,可能会导致内存泄漏等问题。

(六)孤儿进程

与僵死进程相关的一个概念是孤儿进程。当父进程提前退出,而子进程后退出时,子进程就会成为孤儿进程。孤儿进程会被1号init进程领养,由init进程负责回收相关资源。

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

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

相关文章

银河麒麟V10中启用SELinux

银河麒麟V10中启用SELinux 1、启用SELinux1.1 切换到strict模式1.2 注意 2、验证SELinux状态 💖The Begin💖点点关注,收藏不迷路💖 在银河麒麟高级服务器操作系统V10中,可以使用security-switch工具来启用SELinux&…

springboot邮件群发功能的开发与优化策略?

springboot邮件配置指南?如何实现spring邮件功能? SpringBoot框架因其简洁、高效的特点,成为了开发邮件群发功能的理想选择。AokSend将深入探讨SpringBoot邮件群发功能的开发过程,并提出一系列优化策略,以确保邮件发送…

香山南湖架构分析--FE

总体架构 分支预测和指令缓存,通过FTQ达到解耦的目的;FTQ将请求送给ICache,进行取指;取出的指令码通过预译码初步检查分支预测的错误并及时冲刷预测流水线;检查后的指令送入指令缓冲并传给译码模块,最终形成后端的指令…

抓住最后机会!24年PMP认证报名今日开始,流程详解助你成功

为减少同一时间集中报名造成的网络拥堵,本次报名将采取以下形式分地区、分批次开放报名。 一、考试安排 考试时间:2024年11月30日 第一批报名城市 2024年10月9日10:00至10月16日16:00,以下城市的考点将开通报名&…

城市交通场景分割系统源码&数据集分享

城市交通场景分割系统源码&数据集分享 [yolov8-seg-C2f-Faster&yolov8-seg-GhostHGNetV2等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Glob…

FineReport打开报错“配置数据库出错“怎么解决?

配置数据库被锁住,是否重置?将在embed文件夹生成备份并重置 我直接用管理员身份证打开就完美解决了!

fmql之Linux下AXI GPIO、MISC

AXI GPIO 正点原子第41章。 要使用AXI GPIO,就要在vivado工程中,添加相关的IP。 然后dts会自动生成相关的AXi GPIO的设备树内容。 MISC 正点原子第42章。 /***************************************************************Copyright © ALIENTE…

C++--特殊类的设计

下面所实现类的源码:源码链接 不可拷贝类 在C中,我们有时候需要设计一些不可拷贝的类,即不允许用户通过拷贝构造函数或赋值操作来创建该类的副本。这样设计通常是为了确保资源(如文件描述符、窗口句柄等)的唯一性&…

(JAVA)熟悉队列的进阶结构 - 优先队列

1. 优先队列 ​ 普通队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。 ​ 在某些情况下,我们可能需要找出队列中的最大值或者最小值,例如使用一个队列保存计算机的任务,一般情况下计算机的任务都是有…

FTP连接池与多线程上传下载算法实现(C语言)

FTP连接池与多线程上传下载算法实现(C语言) 设计思路伪代码示例C代码示例为了避免多线程环境下FTP连接池在故障重连时导致的竞争条件和core dump问题,我们需要设计一个精细的连接池管理系统,确保在连接重连时,其他线程不会尝试使用该连接。以下是一个简化的设计思路和示例…

开源计算器应用的全面测试计划:确保功能性和可靠性

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…

Navicat图形化设置字段unique

点击索引,选择字段和索引类型即可。

前端学习笔记-JS进阶篇-04

1、深浅拷贝 开发中经常需要复制一个对象。如果直接用赋值会有下面问题: 首先浅拷贝和深拷贝只针对引用类型 1.1、浅拷贝 浅拷贝:拷贝的是地址 常见方法: 1.2.1、 拷贝对象:Object.assgin() / 展开运算符 {...obj} 拷贝对象…

目标检测指标:AP,mAP

目标检测指标:AP,mAP 论文:A Survey on Performance Metrics for Object-Detection Algorithms 文章目录 目标检测指标:AP,mAP摘要1 介绍2 主要的性能指标TP、FP、FNP、RAP A P 11 AP_{11} AP11​ A P a l l AP_{all}…

金慧-综合管理信息系统 LoginBegin.aspx SQL注入复现

0x01 产品描述: 金慧-综合管理信息系统(以下简称“金慧综合管理系统”)是上海金慧软件有限公司基于多年行业系统研发和实施经验,为各类企业量身定制的一套综合性管理解决方案。该系统旨在通过信息化手段,提升企业的管理…

openstack-swift.18421165

对象存储 swift 对象存储 是一种用于存储和管理大量数据的系统。类似于一个超大云盘。可以存储各种文件。(照片,视频,文档等等)。与传统的文件存储不同,对下个存储不关心文件的目录结构和层级关系,而是将每…

嵌入式仿真实验教学平台

一、基本介绍 嵌入式仿真实验教学平台:嵌入式硬件仿真、线上实验教学、虚实结合场景实训 二、案例 AVG场景实训 智能家居场景实训 智慧农业场景实训 智慧物流场景实训

Python【修炼2】

欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 🏠个人专栏:Python 目录 👉🏻map👉🏻lambda👉🏻datetime日期输出格式 👉&#x1f3fb…

Airtest脚本的重构与优化:提升测试效率和可读性

在自动化测试的工作里,编写高效且易于维护的测试脚本是一项挑战,尤其是在应对复杂的测试场景时。Airtest作为一款常用的自动化测试工具,它提供了丰富的API和灵活的脚本编写方式,帮助测试人员高效地开展UI自动化测试。然而&#xf…

头戴式耳机性价比高的有哪些?五大高性价比头戴式耳机推荐!

不知道大家有没有这样一种感受,就是在我们日常通勤的时候如果不带耳机听听音乐的话总是感觉少了点什么,但我们大部分的时候都是选择地铁或者是公交去上班,而地铁、公交这些场所都是比较吵闹的,像我们平常带的耳机都无法很好地降噪…