【Linux】进程状态详解

news2024/11/26 6:21:29

img

Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法…感兴趣就关注我吧!你定不会失望。

本篇导航

  • 0. 五状态进程模型
  • 1. 运行 >> R (running)
  • 2. 浅度睡眠 >> S (sleeping)
  • 3. 深度睡眠 >> D (disk sleep)
  • 4. 暂停 >> T (stopped)
  • 5. 僵尸 >> Z (zombie)
  • 6. 进程优先级

在这里插入图片描述

0. 五状态进程模型

这是操作系统中的五种状态.其中新建状态和退出状态不是很重要,所以通用的为三状态模型也就是:就绪态,阻塞态,运行态

  • 就绪态:需要CPU的进程已经完成了资源调度,在等待分配到CPU
  • 运行态:在CPU上运行的进程所处的状态
  • 阻塞态:因缺少某种资源(例如IO资源,磁盘读写)正在等待的进程

image-20231105230151777

操作系统中这三个状态是理论的,在实际应用中的操作系统围绕这三个状态的核心状态延伸出了许多状态.接下来来看看Linux操作系统中的各种状态.

  1. 运行 “R (running)”
  2. 浅度睡眠 “S (sleeping)”
  3. 深度睡眠 “D (disk sleep)”
  4. 暂停 “T (stopped)”
  5. 僵尸 “Z (zombie)”
  6. 死亡 “X (dead)”

1. 运行 >> R (running)

顾名思义,为正在占用CPU运行的进程.也为操作系统中的运行态

我们写一个这样的程序,让该进程陷入死循环,更方便观察.

#include <stdio.h>
int main()
{
    int cnt = 0;
    while(1)
    {
        cnt++;
    }
    return 0;
}
gcc -o proce proce.c

运行起来后,我们用观察进程的ps指令看看

ps -ajx | head -1 && ps -ajx | grep porce

可以观察到如下情况:

image-20231105232021997

其中STAT表示该进程的运行状态为R

但这里并不是时时刻刻CPU都在运行这个进程的.CPU当中有一个 时间片 的概念,操作系统也维护了一个 运行队列,将所有R状态的进程都放在运行队列上.当一个时间片过后,就执行 进程切换(将进程从CPU上拿下来,换一个在运行队列当中的进程上去).

这是一个并行的过程:在物理上是分段进行,在逻辑上是同时发生

4a00b4c200024fd770aa18fd0e50da4

2. 浅度睡眠 >> S (sleeping)

为操作系统中的阻塞态,因在等待某种资源而无法被CPU调度

将上方的程序进行修改,加入一个printf即可观察.因为CPU运行比IO快很多很多,所以需要IO的进程大多时间都在等待IO.可以观察到S状态

#include <stdio.h>
#include <unistd.h>
int main()
{    
    int cnt = 0;    
    while(1)    
    {        
        printf("hello\n");
        sleep(1);
    }    
    return 0;
}

image-20231105234438109

printf()实际上是封装了系统调用,能访问硬件资源.在进程中每个硬件资源都维护了一个等待队列.

447731e52ec7482c0a1e5714cbdc4dd

需要访问硬件资源的进程,大多时候都处在等待队列中.(因为CPU一下就处理完了)

3. 深度睡眠 >> D (disk sleep)

为操作系统中的阻塞态,因在等待磁盘资源而无法被CPU调度

设想一个这样的场景:

进程给磁盘发送了一个写入的指令,磁盘正在工作.此时进程正在等待磁盘给反馈信号(是否完成作业).突然操作系统内内存不足,需要释放一部分处在阻塞态的进程,这时若释放这种进程.那么磁盘写入丢失了怎么办呢?

所以引入了一个特殊的阻塞态,该状态无法被操作系统调度.仅能根据磁盘反馈的信号做出相应动作(重写 or 停止).不响应任何其他请求

4. 暂停 >> T (stopped)

为操作系统中的阻塞态,这是一种主动让进程停止的状态.

例如我们之前使用的gdb调试.程序运行到我们打的断点时,都相当于给进程发送了一个暂停信号.重新运行的时候再次发送一个继续信号.

我们输入

kill -l

查看kill所有信号

image-20231106100318358

其中18号命令 SIGCONT为继续信号, SIGSTOP为停止信号.

我们运行之前能在屏幕上输出Hello的进程.对其发送停止信号

kill -18 843951

image-20231106100816680

可以直观的看到,提示进程843951被暂停了.我们再使用18号指令让进程继续运行

kill -18 843951

image-20231106101516859

5. 僵尸 >> Z (zombie)

其为处于退出态的前一种状态

一个人在路上跑步,突然间猝死了.警察来先调查原因,将原因告知家属,再通知处理尸体

虽然例子有点抽象.但很形象.进程发出结束信号时,需要先将自己的结束状态告诉家属(父进程)是否正常结束等…

此时进程处在的就是僵尸状态.

编写以下代码创建一个进程,子进程比父进程更快回收.可以清楚的观察到僵尸

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
    pid_t id = fork();
    if(id == 0)
    {
        int cnt = 10;
        while(cnt--)
        {
            printf("i am a child process my pid %d\n",getpid());
        }
        exit(0);
    }
    int cnt = 20;
    while(cnt--)
    {
        printf("i am a father process my pid %d\n",getpid());
    }
    return 0;
}

image-20231106103451282

当子进程先退出后处在僵尸状态,会等待父进程进行回收.父进程结束后,会自动回收子进程一起带走.

那如果父进程比子进程先结束呢?

上次我们说到 所有进程的父进程都是bash.所以一个进程成为了孤儿进程(父进程比子进程早结束),此时就会将自己的父进程转为bash.

6. 进程优先级

因为资源是有限的,进程是多个的.所以注定进程间具有优先级的概念.

ps -alx | head -1 && ps -alx | grep porce

image-20231106104450230

其中PRI与NI就是进程优先级与NICE值.

有这样的计算公式: **PRI(新)=PRI(旧)+NICE **

其中PRI旧永远都是从80开始,值越小优先级越大,NICE取值范围为[-20,19]

可以在ROOT权限下使用top命令调整NICE值,进而改变某进程的优先级

具体的为:先运行top,然后输入r即可调整

在运行队列中,会维护两个优先级队列,一个为等待队列,一个为当前正在运行的队列.

struct runqueue{
  bitmap isempty;
  task_struct **run;
  task_struct **wait;
  task_struct *running[140];
  task_struct *waiting[140];
};

r即可调整

在运行队列中,会维护两个优先级队列,一个为等待队列,一个为当前正在运行的队列.

struct runqueue{
  bitmap isempty;
  task_struct **run;
  task_struct **wait;
  task_struct *running[140];
  task_struct *waiting[140];
};

其中run指针指向当前正在运行的队列,其按优先级进行分级.依次从下往上运行.
在此过程中,若有新的进程加入运行队列,则会被放在等待队列中.
当运行队列运行完毕时,则将run指针与wait指针互换.原运行队列变为等待队列,等待队列变为运行队列.

image-20230905164632777

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

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

相关文章

skynet学习笔记01— skynet开发环境搭建(超详细)与第一个skynet程序

00、参考资料 https://blog.csdn.net/qq769651718/category_7480207.html 01、前置准备 开发所在目录 mhzzjmhzzj-virtual-machine:~/work/skynetStudy$ pwd /home/mhzzj/work/skynetStudy前置准备 mhzzjmhzzj-virtual-machine:~/work/skynetStudy$ sudo apt install lua5…

注册电气工程师证书挂靠有风险吗?考试难度很高是吗?前景怎么样

一.先说证书挂靠问题&#xff0c;毫无疑问&#xff0c;有风险&#xff0c;远的不说咱说说近的&#xff0c; 比如下面这张图 从上面这张图可以看出来&#xff0c;哪怕是2023&#xff0c;还有陆陆续续的人因为挂靠的问题被处罚&#xff0c;所以我的建议是能不挂就不挂&#xff0c…

qt opengl 绘制点、线、三角形、多边形(二)

文章目录 一、相关宏定义参数二、代码及示例图1. 点 LG_POINTS 0x00002. 线 GL_LINES 0x00013. 线 GL_LINE_LOOP 0x00024. GL_LINE_STRIP 0x00035. GL_TRIANGLES 0x00046. GL_TRIANGLE_STRIP 0x00057. GL_TRIANGLE_FAN 0x00068. GL_QUADS 0x00079. GL_QUAD_STRIP 0x000810. GL_…

第八章 Python类(面向对象编程)

系列文章目录 第一章 Python 基础知识 第二章 python 字符串处理 第三章 python 数据类型 第四章 python 运算符与流程控制 第五章 python 文件操作 第六章 python 函数 第七章 python 常用内建函数 第八章 python 类(面向对象编程) 第九章 python 异常处理 第十章 python 自定…

数票通批量开票小妙招,双11开票不用愁

每年双十一都是电商企业和财务“疯狂”的日子&#xff0c;随着疫情的回暖&#xff0c;消费者的消费能力蹭蹭上涨&#xff0c;商家的口袋盆满钵满&#xff0c;而财务的加班永无休止&#xff0c;批量开票成为财务人摆脱双十一加班的必备技能。 面对双十一狂欢&#xff0c;相信不少…

一文带你深入浅出Web的自动化测试工具Selenium【建议收藏】

文章目录 前言第01节 Selenium概述第02节 安装浏览器驱动&#xff08;以Google为例&#xff09;第03节 定位页面元素1. 打开指定页面2. id 定位3. name 定位4. class 定位5. tag 定位6. xpath 定位7. css 选择器8. link 定位9. 示例 有道翻译 第04节 浏览器控制1. 修改浏览器窗…

3D目标检测实战 | 图解KITTI数据集评价指标AP R40(附Python实现)

目录 1 准确率和召回率2 P-R曲线的绘制3 AP R11与AP R40标准4 实际案例 1 准确率和召回率 首先给出 T P TP TP、 F P FP FP、 F N FN FN、 T N TN TN的概念 真阳性 True Positive T P TP TP 预测为正(某类)且真值也为正(某类)的样本数&#xff0c;可视为 I o U > I o U t…

3Dmax Vary 渲染 玻璃 水 啤酒 的参数尝试

折射率&#xff1a; 空气折射率为1.0 水折射率一般 1.3 -1.4 &#xff0c;啤酒折射率一般 1.4-1.55 玻璃折射率 一般 1.5-1.7 金刚石钻石 2.0 透明物体 密度越大 折射率越高。折射&#xff1a;同一束光在不同密度介质传播时发生的 光路弯折。如果密度不断发生变化&#…

C++常用格式化输出

在C语言中可以用printf以一定的格式打印字符&#xff0c;C当然也可以。 输入输出及命名空间还不太了解的小伙伴可以看一看C入门讲解第一篇。  在C中&#xff0c;可以用流操作符&#xff08;stream manipulators&#xff09;控制数据的输出格式&#xff0c;这些流操作符定义在2…

UE5——源码阅读——4——引擎预初始化

预初始化的开始处理和结束处理 将GEnginePreInitPreStartupScreenEndTime设置为平台的时间 ON_SCOPE_EXIT 这个就是在程序结束后执行一个Lambda&#xff0c;这个弘的目的是简化代码确保正确的时机正确的执行清理操作&#xff0c;降低因资源泄露而导致BUG的概率 处理延迟注册…

【GEE】基于GEE-Landsat8数据集地表温度反演(LST热度计算)

老样子&#xff0c;最近在做生态方面的项目&#xff0c;然后需要分析城市的热岛效应&#xff0c;想了想还是用GEE计算比较简单&#xff0c;直接下载影像太麻烦了。所以在网上看看了资料&#xff0c;踩了踩坑终于是将代码写出来了。秉承着取之于民、用之于民的想法&#xff0c;今…

如何解决msvcp140.dll文件丢失问题,msvcp140.dll丢失的解决方法

在使用电脑时&#xff0c;有时我们可能会遇到一些错误提示&#xff0c;比如“找不到msvcp140.dll文件”。这是因为某些程序需要依赖于msvcp140.dll文件才能正常运行。这个问题是可以解决的,大家不需要担心&#xff0c;而且其解决的方法是有很多种的&#xff0c;今天我们就来给大…

VS编译器中创建新源文件,自动添加----#define _CRT_SECURE_NO_WARNINGS 1

每次创建新的源文件时都需要添加比较麻烦&#xff0c;我们让每次创建时自动添加&#xff0c;步骤如下&#xff1a; 1、右键编译器--->属性--->目标&#xff08;存放的是编译器的文件位置我们找到文件的位置&#xff09; 2、如下步骤找到“newc file.cpp”文件&#xff0…

MySQL基础之约束、多表查询、事务【基础完结】

1 SQL约束 SQL约束是用于规定表中的数据规则&#xff0c;如果存在违反约束的数据行为&#xff0c;行为会被终止。 1.1 如何创建约束 • 在创建表的时候进行规定&#xff08;create table&#xff09;• 修改表的时候进行规定&#xff08;alter table&#xff09; 1.2 约束的…

设计师的宝库:5个供应免费素材的设计网站

今天给大家推荐五个设计素材网站&#xff0c;设计师看到就要码住&#xff0c;码住就是灵感。 即时设计 即时设计是一个可在线使用的设计资源网站&#xff0c;在网页中打开「即时设计」的官网&#xff0c;登录账号后即可使用即时设计提供的设计资源。 即时设计 - 可实时协作的…

史上最全Windows安全工具汇总

史上最全Windows安全工具锦集来源于网络整理&#xff0c;安全性自测。 下载方式&#xff1a;史上最全Windows安全工具汇总

为了理直气壮怼回去,写了一个日志切面输出接口出入参数

1.背景 我们在日常排查问题过程中知道&#xff0c;入参传错是导致接口调用失败的常见原因之一。特别是提供给第三方调用的回调接口和openAPI接口&#xff0c;由于无法保证第三方开发人员的水平&#xff0c;经常问题不断&#xff0c;反反复复找你问为啥掉不通&#xff0c;甚至吐…

多人游戏小程序源码系统 带完整的搭建教程

现如今&#xff0c;人们对于娱乐和社交的需求也在不断提高。多人游戏作为一种能够满足人们社交需求的游戏类型&#xff0c;越来越受到用户的欢迎。同时&#xff0c;小程序作为一种轻量级的应用程序&#xff0c;在微信等平台上得到了广泛的应用和推广。因此&#xff0c;开发多人…

【LeetCode力扣】287.寻找重复数(中等)

1、题目介绍 原题链接&#xff1a;287. 寻找重复数 - 力扣&#xff08;LeetCode&#xff09; 示例 1&#xff1a; 输入&#xff1a;nums [1,3,4,2,2] 输出&#xff1a;2示例 2&#xff1a; 输入&#xff1a;nums [3,1,3,4,2] 输出&#xff1a;3提示&#xff1a; 1 < n &l…

hbase代码报错(以及解决方法)

》》》直接上代码 package HBase_Apiimport org.apache.hadoop.conf.Configuration import org.apache.hadoop.hbase.{HBaseConfiguration, TableName} import org.apache.hadoop.hbase.client.{Connection, ConnectionFactory, Get, Put} import org.apache.hadoop.hbase.ut…