【Linux】进程的状态详解

进程的状态详解

    • 一、各种状态的概念
    • 二、运行状态的详细介绍
    • 三、阻塞状态详解
    • 四、挂起状态和阻塞状态的关系
    • 五、观察各种状态在linux中的表示
      • 1.运行态R
      • 2.睡眠态S
      • 3.暂停态T
      • 4.深度睡眠状态D
      • 5.僵尸状态Z
      • 6.孤儿进程

一、各种状态的概念

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

  1. R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
  2. S睡眠状态(sleeping)(阻塞状态): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠)
  3. T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
  4. D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
  5. X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。
  6. 僵尸状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用,后面讲)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程

现在着重讲的三种状态是:运行状态、阻塞状态、就绪状态。

  1. 运行状态:进程已经占用CPU,在CPU上进行
  2. 就绪状态:具备运行条件但是由于没有CPU可用,所以暂时不能运行
  3. 阻塞状态:由于等待某个事件或某个资源而不能运行的状态,如:等待系统调用,IO操作等;

进程三态模型

在这里插入图片描述

  • 运行态----->就绪态 :时间片使用完或被强行占用
  • 运行态----->阻塞态:请求服务器后等待响应,或等待某个信号的到来
  • 就绪态----->运行态:进程调度
  • 阻塞态----->就绪态:请求服务器完成,或等待的信号已经到来

五大基本状态模型

在这里插入图片描述

创建状态:进程刚刚被创建出来的状态

二、运行状态的详细介绍

因为cpu的核心个数是远少于进程个数的,那么进程是如何在CPU里面运行的呢?

  • 通过CPU在内核中维护的运行队列来实现的!一般来说一个CPU对应一个运行队列!
    让进程入CPU的本质就是将进程入这个运行队列!——但是也不是让进程的代码入队列!而是让进程对应的**PCB(task_struct结构体对象)**入这个运行队列中!!所以让进程去排队本质就是让进程的PCB去排队!

  • 举个例子 我们去面试我们是将描述我们的信息的简历投到公司的邮箱里面
    公司也是通过看一个个的已经排序的简历来挑选的,最后也是通过简历来联系到我们的
    CPU的运行逻辑也是一样的!CPU的运行速度是非常快的!所以CPU将运行队列里面的程序全部轮转完一遍也 是很快的

  • 因此运行队列上进程就必须随时都准备好让CPU来调度运行它
    运行队列里面的一个个进程(PCB)就叫做运行状态
    可能这样说很奇怪但是将白了 只要在运行队列里面的进程就是运行状态

要区分一下!不是进程在CPU上跑了才叫运行状态,只要进程在运行队列里面!那么这个进程就叫运行状态,进程状态是为了来区分进程是否在运行队列里面!不是为了区分是否则在被CPU运行!因为CPU运算速度是非常快的所以没有意义!

总结
一个CPU对应一个运行队列!
让进程进入队列,本质就是将该进程的task_struct结构体(PCB)对象放入运行队列
进程PCB在运行队列中就是R(linux下的运行状态表示)

那么这个“状态”是保存再哪里的呢?
状态是一种进程的内部属性!那么进程状态也是在**task_struct(PCB)**里面!
一般在内核里面都是用整数来表示一种状态这个整数是几

三、阻塞状态详解

根据冯诺依曼体系知道 CPU虽然十分的快!但是外设的速度相比起来就十分的慢了
进程或多或少的要去访问外设!例如:我们要想写一个程序让显示器显示一句话
但是访问外设的往往都不止有一个进程(如:访问显示器、访问键盘等),所以这时候进程就要进入等待,这样意味着进程不止要占用CPU资源 同时也需要占用外设资源,所以为了应对多个进程的访问!那么每种外设的结构体里面都有和CPU运行队列相似的的等待队列,而此时这个被放在等待队列中的进程的状态我们就称之为阻塞状态

  • 这些队列都有各自的硬件维护!
  • 当一个CPU正在执行某个进程!而这个进程的某个代码要进行写入操作!那么就要访问磁盘,可是现在访问磁盘的进程已经有很多个了。自然不可能你想访问就访问,必须排队!
  • 这时候CPU就不会选择等待这个进程在磁盘中写入完毕,会直接执行下一个进程!(如果等待的话那么就很拖累cpu的速度!降低效率,这是操作系统不想看到的)这样就可以保证CPU永远执行运行的进程!
  • 同时原先的这个进程会被从CPU的运行队列中剥离,然后放入等待队列中!
    而此时这个被放在等待队列中的进程的状态我们就称之为阻塞状态

在这里插入图片描述
注:进程状态的修改实际上就是将进程的PCB放入不同的队列中

四、挂起状态和阻塞状态的关系

从上面我们知道一旦一个进程需要访问外设但是无法立刻访问到的时候,进程PCB就会进入等待队列变为等待状态。
如果有很多个进程同时进入阻塞状态呢?

  • 从上面我们知道一旦磁盘空出来进程也不会被立刻调度。而是操作系统先把进程状态修改,然后放入CPU的运行队列里面
  • 如果有大量的阻塞状态的进程那么就意味着要等待很长时间(短期内不会被使用),然而这些进程的PCB和程序数据代码都是要占内存的!运行的程序也要占内存
  • 当存在大量的阻塞状态的进程时就会导致内存不足。这时想要运行新进程,操作系统就会将这些阻塞的进程的PCB保留在内存但是代码和数据暂时保存在磁盘上!不放在内存里面这样就可以节省一部分的空间!如图:

在这里插入图片描述
当某个进程准备完毕以后,会重新加载该进程的代码和数据进入内存,然后将该进程移入运行队列中。

阻塞和挂起状态的区别:

  • 挂起是一个行为,而阻塞是进程的一种状态
  • 进程存放的位置不同:挂起是将进程移到外存中,而处于阻塞状态的进程还是在内存中
  • 原因不同:导致进程被挂起的原因一般是内存不足或者是系统、用户的请求,协调、修改进程,研究进程的状态等,进程阻塞是进程正在等待某一事件发生,可能是等待资源或者响应等(eg.等待I/O完成等)而暂时停止运行
  • 挂起对应的行为是激活,将外存中的进程调入内存中。而处于阻塞状态的进程需要其他进程或系统唤醒
  • 挂起是被动的行为,进程被迫从内存中移至外存中。而进入阻塞可以看成是一个主动的行为(eg.进程I/O时,进程在等待I/O设备完成时,进程主动进入阻塞状态,I/O完成,进程被激活)

五、观察各种状态在linux中的表示

1.运行态R

运行代码:

#include<stdio.h>
int main()
{
    while(1){}
    return 0;
}

查看代码:

ps ajx | head -1 && ps ajx | grep a.out | grep -v grep

结果:

在这里插入图片描述

可以看到运行态R;

2.睡眠态S

运行代码:

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

结果:

在这里插入图片描述

可以看到进程状态S

这里就会有人好奇了,为什么和上面的运行代码对比之下,只是多加了一行打印就是睡眠状态了呢?

原因:CPU的运行速度非常的快,而进程想要打印一行代码就得访问一次外设,访问外设的速度是非常慢的,所以进程每次打印时都要等待IO就绪才能打印,也就是我们说的等待某种资源。所以进程处于睡眠(阻塞)状态;

3.暂停态T

运行代码:

#include<stdio.h>
int main()
{
    while(1){}
    return 0;
}

结果:

在这里插入图片描述

这里运行代码和运行状态的代码一样,这里使用了 kill -19 PID指令,让进程处于暂停状态

关于+号
我们上面也看到了有的进程状态后面有个+号 而有的后面突然就没有了这是怎么回事?

这样的进程我们称为前台进程!也就是说一旦这个程序运行了shell命令行就无法获得命令行解析了!除了使用ctrl+c来停止进程!

而没有+号的进程我们称之为前台进程。

4.深度睡眠状态D

深度睡眠一般是很难看见的!只在高并发高IO的时候常见!

为了方便理解我们先假设有一个进程A 拿着几十万条的用户数据向磁盘写入

磁盘和其他外设不同保存着数据很重要!其他外设可以休眠后随便终止掉!但是磁盘不一样
一般来说当出现大规模的数据IO的时候,一旦出现了内存紧缺,操作系统首先会去挂起进程,但是一旦连挂起都无法解决的时候!那么操作系统就会自主的杀掉进程!

在这里插入图片描述

因为内存紧缺导致了进程A被杀掉!但此时进程A正在向磁盘写入数据,那么数据很有可能会发生丢失!

**所以为了防止这种情况!所以有了D状态!**这种状态下操作系统即使是内存紧缺操作系统也不会去杀掉进程!防止数据的丢失!

D状态直白的讲——该状态下的进程,无法被OS杀掉!只能通过断点,或者进程自己醒来来解决!

我们发现linux下其实没有写什么新建,就绪,阻塞因为这些状态都是以操作系统的角度来进行的一个总结!
像是D ,T ,S都可以被归类到阻塞或者挂起!像是运行状态在 linux下就表现为R

5.僵尸状态Z

补充:死亡状态X:当进程死亡以后变成的状态,速度非常的快,我们是捕捉不到的。只要知道有就行了

僵尸状态为什么存在?
首先我们要明白 进程被创建 一定是为了完成某种任务!
当执行任务的时候 我们是不是得知道任务执行的如何呢?当然也有可能不关心
但是不管怎么样,操作系统一定会把任务的结果给保留下来,无论我们是关心还是不关心

  • 如果我们想要知道进程完成的怎么样,就代表进程退出的时候,不可以立即释放该进程对应的资源!要保存一段时间让父进程或操作系统进行读取
  • 进程从退出到被操作系统/父进程获取读取结果之前保留的资源的这段时间我们称之为Z状态!再被操作系统/父进程读取结果后才会被从Z状态转换成X状态!最后被资源回收!
  • 举个例子:当我们在路上遇到了一个因为跑步倒下的人,那个人疲劳猝死了,这时候我们绝大多数人应该会选择报警,等警察来了之后,警察还会让人去做一个医学鉴定,确认这个人已经死亡,一旦确定死亡警察就会让家属去处理后事
    而我们把进程比作那个猝死的人 从倒下到完成医学鉴定的这段时间 我们就可以称为僵尸状态,等医学检测出来(操作系统/父进程读取玩结果)就是从Z状态转换成X状态
  • 僵尸状态是一个很大的问题!——即进程已经退出但是资源却没有办法被释放这就是一种内存泄漏!!

僵尸进程的危害:

  • 进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎 么样了。可父进程如果一直不读取,那子进程就会一直处于Z状态。
  • 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话 说,Z状态一直不退出,PCB就一直都要维护。
  • 那一个父进程创建了很多子进程,就是不回收,就会造成内存的浪费,内存泄漏。
  • Z状态是不能kill指令杀死的!因为Z状态本身就已经是“死”的没法杀死

解决方法:以进程等待的方式回收处于僵尸状态的进程

6.孤儿进程

孤儿进程:父进程先退出,子进程就称之为“孤儿进程”

  1. 为什么父进程被杀掉之后不存在僵尸状态呢?——因为父进程也有它的父进程!命令行下面的所有进程都是bash的子进程!父进程被杀掉后直接被bash回收了!我们能看到子进程的僵尸状态是因为它对应的父进程没有进程回收!
  2. 当一个进程的父进程先退出后,那么这个进程就会被操作系统“领养”,也就意味着此时该进程的PPID变成了1。
  3. 为什么会被“领养”呢?如果不领养那么子进程对应的僵尸进程,就无人回收资源了!
  4. 系统领养后,这个子进程的+号会消失,说明这个子进程变成了一个后台进程!——如果前台进程创建的子进程被孤儿了,那么会自动变成一个后台进程!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python高级之简单爬虫实现

一、前言 场景1&#xff1a;一个网络爬虫&#xff0c;顺序爬取一个网页花了一个小时&#xff0c;采用并发下载就减少到了20分钟。 场景2&#xff1a;一个应用软件优化前每次打开网页需要3秒&#xff0c;采用异步并发提升到了200毫秒。 假设一个工程的工作量为100&#xff0c…

web——upload-labs——第十关——.空格.绕过

审计源码 这次先删除文件名左右的空格&#xff0c;然后又删除了我们文件末尾的.&#xff0c;其次将我们上传的文件名转换为小写&#xff0c;删除文件末尾的::$DATA&#xff0c;最后又删除了文件名左右两侧的空格 根据他的逻辑&#xff0c;我们可以构造文件名phpinfo.php. .就是…

Percona XtraBackup备份docker版本mysql 5.7

my.cnf配置文件 [client] default_character_setutf8[mysqld] # 数据存储目录&#xff08;必须手动指定&#xff09; datadir/var/lib/mysql/data# 字符集 collation_server utf8_general_ci character_set_server utf8 # 二进制日志 server-id1 log_bin/var/log/mysql/binl…

JavaWeb之Vue

前言 这一节讲Vue 1. Vue概述 这些都是DOM的操作 原来模型和视图不能实现同步变化&#xff0c;但是Vue就可以了 2. 快速入门 1. 2. <script src"js/vue.js"></script><div id"app"> <!-- 准备一个input输入框,绑定一个模…

汽车资讯新篇章:Spring Boot技术启航

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

Windows注册表基础学习

修改注册表让cmd ascii输出有颜色 reg add HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1 如何打开注册表编辑器 运行regedit 按下"Winr"组合键&#xff0c;在打开的"运行"对话框中输入"regedit"&#xff0c;单击"确定"…

C++ | Leetcode C++题解之第564题寻找最近的回文数

题目&#xff1a; 题解&#xff1a; using ULL unsigned long long;class Solution { public:vector<ULL> getCandidates(const string& n) {int len n.length();vector<ULL> candidates {(ULL)pow(10, len - 1) - 1,(ULL)pow(10, len) 1,};ULL selfPrefi…

Debezium-MySqlConnectorTask

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 MySqlConnectorTask&#xff0c;用于读取MySQL的二进制日志并生成对应的数据变更事件 整体架构流程 技术名词解释 数据库模式&#xff08;Database Schema&#xff09; 数据库模式是指数据库中数据的组织结构和定义&…

【WPF】Prism学习(二)

Prism Commands 1.命令&#xff08;Commanding&#xff09; 1.1. ViewModel的作用&#xff1a; ViewModel不仅提供在视图中显示或编辑的数据&#xff0c;还可能定义一个或多个用户可以执行的动作或操作。这些用户可以通过用户界面&#xff08;UI&#xff09;执行的动作或操作…

如何实现主备租户的无缝切换 | OceanBase应用实践

对于DBA而言&#xff0c;确保数据库的高可用性、容灾等能力是其日常工作中需要持续思考和关注的重要事项。一方面&#xff0c;可以利用数据库自身所具备的功能来实现这些目标&#xff1b;若数据库本身不提供相应功能&#xff0c;DBA则需寻找其他工具来增强数据库的高可用性和容…

壁仞科技上市前最后一波 校招 社招 内推

随着美国大选结束&#xff0c;国内GPU 产业得到空前的的发展空间&#xff0c;国内芯片相关股票一片飘红。 国内大型 GPU厂商壁仞科技&#xff0c;摩尔线程等正紧锣密鼓地加紧上市。 GPGPU 芯片赛道来到了史无前例的红利点&#xff0c;抓住机会&#x1f4aa; 壁仞科技正在火热…

前端监控之sourcemap精准定位和还原错误源码

一、概述 在前端开发中&#xff0c;监控和错误追踪是确保应用稳定性和用户体验的重要环节。 随着前端应用的复杂性增加&#xff0c;JavaScript错误监控变得尤为重要。在生产环境中&#xff0c;为了优化加载速度和性能&#xff0c;前端代码通常会被压缩和混淆。这虽然提升了性…

使用Web Push Notifications提升用户参与度和留存率

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 使用Web Push Notifications提升用户参与度和留存率 使用Web Push Notifications提升用户参与度和留存率 使用Web Push Notifica…

量化选股日常操作日记-11-ai眼镜-润欣科技

用 微信小程序 梦想兔企业智能风险分析助手 &#xff0c;选择AI眼镜板块&#xff0c;挖掘了几个合适的股&#xff0c;分析下来感觉 润欣科技 比较安全些适合观察&#xff0c;几块到十几块波动&#xff0c;企业基本面也没有特别大问题。就是现在价位在周期波动高位&#xff0c;下…

【WPF】Prism学习(五)

Prism Commands 1.错误处理&#xff08;Error Handling&#xff09; Prism 9 为所有的命令&#xff08;包含AsyncDelegateCommand&#xff09;提供了更好的错误处理。 避免用try/catch包装每一个方法根据不同遇到的异常类型来提供特定的逻辑处理可以在多个命令之间共享错误处…

Intern大模型训练营(八):Llamaindex RAG 实践

1. 基于 LlamaIndex 构建自己的 RAG 知识库 首先在Intern Studio中申请30% A100的开发机。 进入开发机后&#xff0c;创建新的conda环境&#xff0c;命名为 llamaindex&#xff0c;在命令行模式下运行&#xff1a; conda create -n llamaindex python3.10 复制完成后&#…

台式电脑没有声音怎么办?台式电脑没有声音解决详解

台式电脑一般来说都是没有内置扬声器的&#xff0c;需要连接耳机或者是音响才可以播放音乐。那么如果遇到台式电脑没有声音的问题&#xff0c;我们也需要确认这些设备硬件有没问题&#xff0c;知道原因才可以进行处理。下面本文将为你介绍台式电脑没有声音的可能原因和解决方法…

vue2项目中在线预览csv文件

简介 希望在项目中&#xff0c;在线预览.csv文件&#xff0c;本以为插件很多&#xff0c;结果都只是支持excel&#xff08;.xls、.xlsx&#xff09;一到.csv就歇菜。。。 关于文件预览 vue-office&#xff1a;文档、 查看在线演示demo&#xff0c;支持docx、.xlsx、pdf、ppt…

H.265流媒体播放器EasyPlayer.js视频流媒体播放器关于直播流播放完毕是否能监听到

EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;无须安装任何插件&#xff0c;起播快、延迟低、兼容性强&#xff0c;使用非常便捷。 EasyPlayer.js播放器不仅支持H.264与H.265视频编码格式&#xff0c;也能支持WebS…

WordPress设置自动更新CSS版本号

WordPress 通常会在引用 CSS 文件时添加版本号参数&#xff08;?verx.x.x&#xff09;。如果版本号未更新&#xff0c;浏览器可能继续加载旧的文件。 解决方法&#xff1a;确保你在 functions.php 文件中正确加载了 CSS 文件&#xff0c;并动态更新版本号。例如在functions.p…