【Linux详解】进程的状态 | 运行 阻塞 挂起 | 僵尸和孤儿状态

目录

        操作系统中

运行状态

阻塞状态

进程状态转换

 Linux系统中

查看进程状态

深度睡眠状态

T 暂停状态

Z 僵尸状态

 孤儿状态

文章手稿


xmind: 

引言

介绍系统中的进程状态及其管理方式。将通过结合操作系统原理和实际代码示例,详细说明进程的各种状态、转换过程以及处理方法。

操作系统中

一个进程通常有三种状态

  • 就绪状态(Ready):表示进程已经具备运行所需要的一切条件,只需要等待CPU的分配就可以运行。进程处于就绪状态时,通常会被添加到就绪队列,等待调度器分配CPU资源
  • 运行状态(Running):表示进程正在被CPU执行。处于运行状态的进程正在使用CPU进行计算或其他操作
  • 阻塞状态(Blocked):表示进程因为某些原因暂时无法继续执行,需要等待一些特定条件的解除之后才能继续运行。例如,当进程等待I/O操作完成或者等待某个资源可用时,会转入阻塞状态。进程在阻塞状态时,通常会被移动到阻塞队列中,等待条件的满足。

我们下面将对运行,阻塞,和阻塞挂起进行介绍~ 

运行状态

 进程只要在运行队列中,就叫做 运行态

阻塞状态

关于进程:

① 一个进程使用资源的时候,可不仅仅是在申请 CPU 资源
② 进程可能会申请其它资源:磁盘、网卡、显卡,显示器资源……

如果我们申请 CPU 资源无法暂时无法得到满足,这就需要排队的 "运行队列" 。那么如果我们申请其他慢设备的资源呢?是需要排队的(task_struct 在进程排队)。

当访问某些资源(磁盘,网卡等),如果该资源暂时没有准备好,或者正在给其他进程提供服务,那么此时:

① 当前进程要从 runqueue 中逐出。
② 将当前进程放入对应设备的描述结构体中的waitqueue 。

进程状态:看PCB在哪个队列

内存不足了,操作系统就会把 该进程的代码和数据置换到磁盘上,进行 进程挂起

进程状态转换

进程状态的转换可以通过以下示例说明:

#include <stdio.h>
#include <unistd.h>

int main() {
    while (1) {
        printf("进程[%d]正在运行...\n", getpid());
        sleep(1); // 模拟阻塞状态
    }
    return 0;
}

通过运行上述代码并观察进程状态,可以理解进程在不同状态之间的转换过程。

三种状态的图示如下:


 Linux系统中

进程状态用整数表示,这些整数存储在进程的task_struct结构体中。常见的进程状态包括:运行(R)、睡眠(S)、磁盘睡眠(D)、停止(T)、死亡(X)、僵尸(Z)和孤儿进程

进程状态一览

状态代码状态名称描述
R运行(Running)进程正在运行或在运行队列中等待
S睡眠(Sleeping)进程在等待某事件完成,可被信号唤醒
D磁盘睡眠(Disk Sleep)进程在等待I/O操作完成,不可被信号唤醒
T停止(Stopped)进程被暂停,可通过信号恢复
X死亡(Dead)进程已终止,从进程列表中移除
Z僵尸(Zombie)进程已退出,父进程尚未读取其状态
孤儿(Orphan)父进程已退出,被init进程收养

查看进程状态

使用ps auxps axj命令可以查看系统中进程的状态。例如:

ps aux
ps axj

这些命令输出的状态字段展示了进程当前的状态。

背后的原因让人暖心,cpu太快了,print显示器等待的时间在他看来就是在sleep了

深度睡眠状态

这个D状态我们就不模拟了……可能会把我的机子磁盘打满(害怕.dog) 


T 暂停状态

比如看视频,听音乐,下载,都会有暂停。当你点击暂停的时候下载对应的代码就不跑了,此时这个进程你就可以认为是暂停状态。

再比如说我们调试程序,让程序打断点之后让程序运行起来,程序在打断点处停住的时候是将进程暂停了,所以你在gdb 调试或在 VS 下调试时你会发现程序会停下来,这就是暂停

是进程挂起的一种。

我们可以先来看一下kill

接下来可以来尝试一下;

$ kill -19 4026,就会发现

gdb下的暂停状态,测试一下

$ gdb process  # 进入gdb调试
(gdb) l        # 查看代码
(gdb) b 9      # 打断点
q + 回车       # 退出

Z 僵尸状态

僵尸状态:当一个 Linux 中的进程退出的时候,一般不会直接进入 X  状态(死亡,资源可以立马被回收),而是进入 Z 状态。

为什么呢~

进程为 Z 状态,就是为了维护退出信息,可以让父进程或者 OS 读取记录的,退出信息会写入 test_struct。

以下是创建僵尸进程的代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    pid_t id = fork();
    if (id < 0) {
        perror("fork");
        return 1;
    } else if (id == 0) { // 子进程
        printf("子进程[%d]开始运行...\n", getpid());
        sleep(5);
        printf("子进程[%d]退出...\n", getpid());
        exit(0);
    } else { // 父进程
        printf("父进程[%d]正在睡眠...\n", getpid());
        sleep(30); // 父进程延迟回收子进程
    }
    return 0;
}

 我们可以写一个监控脚本来看一下~

while :; do ps axj | head -1 && ps axj | grep mytest | grep -v grep; sleep 1; echo "######" ; done

在另一个终端中运行ps命令可以看到子进程进入僵尸状态。

僵尸进程的危害

僵尸进程虽然不再运行,但它们仍然占用系统资源(如进程控制块task_struct)。如果父进程不及时回收子进程,会导致系统资源浪费,甚至内存泄漏。

避免僵尸进程

可以通过以下方式:

  1. 父进程及时调用wait()waitpid()回收子进程。
  2. 使用信号处理机制,在子进程退出时通知父进程进行回收。

 孤儿状态

孤儿进程:父亲没了(bushi

即:父进程先退出了,子的父就变成1 号进程了,相当于被os领养了

测试一下:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
 
int main(void) {
    pid_t id = fork();
    if (id == 0) {
        // child
        int cnt = 5;
        while (1) {  // 死循环,孩子进程就不退了
            printf("我是子进程,我还剩下 %ds\n", cnt--);
            sleep(1);
        }
        printf("我是子进程,我已经变僵尸了,等待被检测\n");
        exit(0);
    }
    else {
        // father
        int cnt = 3;
        while (cnt) {
            printf("我是父进程,我: %d\n", cnt--);
            sleep(1);
        }
        exit(0);
    }
}

 监控一下:

 while :; do ps axj | head -1 && ps axj | grep mytest | grep -v grep; sleep 1;echo "######";done

我们可以top看一下1究竟是什么

 

❓ 疑问:父进程退出,为什么父进程没有变成僵尸?我们怎么没有看到父进程 为Z  ?

  • 那是因为父进程的父进程是bash ,它会自动回收它的子进程,也就是这里的父进程。这里之所以没有看到父进程变成僵尸,是因为被 bash 回收了, z->x 的状态很快,所以你没看到
  • 那为什么刚才我自己代码中的父进程创建的子进程,父进程没有回收子进程呢?那是因为你的代码压根就没有写回收,所以你的子进程就没有回收

那我们怎么暂停呢,ctrl+c 只能干掉前台进程,

所以孤儿进程就要用到我们的杀进程:kill -9来暂停啦


文章手稿

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

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

相关文章

Java Stream API揭秘:掌握List流操作,打造高效数据处理流程

序言 Java Stream API是Java 8中引入的一个非常重要的功能组成部分&#xff0c;它提供了一种声明式的处理数据集合的方法。它主要特点是基于函数式编程的理念&#xff0c;允许我们以更加简洁、高效的方式进行集合的处理、转换和过滤。通过Stream API&#xff0c;我们可以灵活地…

暗黑4PTR怎么参与测试 暗黑4第五赛季怎么参加PTR测试教程

暗黑破坏神4作为暗黑破坏神系列的最新作品&#xff0c;自从2023年上线就受到了一众好评。游戏是动作冒险类角色扮演游戏&#xff0c;游戏的背景设定在一个腐化的圣休瑞亚大陆上&#xff0c;玩家们可以五种职业中选择自己喜爱的游戏进行游戏。 暗黑破坏神4第五赛季现在已经开启P…

机器学习数学原理专题——线性分类模型:损失函数推导新视角——交叉熵

目录 二、从回归到线性分类模型&#xff1a;分类 3.分类模型损失函数推导——极大似然估计法 &#xff08;1&#xff09;二分类损失函数——极大似然估计 &#xff08;2&#xff09;多分类损失函数——极大似然估计 4.模型损失函数推导新视角——交叉熵 &#xff08;1&#x…

SpringCloud_GateWay服务网关

网关作用 Gateway网关是我们服务的守门神&#xff0c;所有微服务的统一入口。 网关的核心功能特性&#xff1a; 请求路由和负载均衡&#xff1a;一切请求都必须先经过gateway&#xff0c;但网关不处理业务&#xff0c;而是根据某种规则&#xff0c;把请求转发到某个微服务&a…

Python数据分析-糖尿病数据集数据分析

一、研究背景介绍 糖尿病是美国最普遍的慢性病之一&#xff0c;每年影响数百万美国人&#xff0c;并对经济造成重大的经济负担。糖尿病是一种严重的慢性疾病&#xff0c;其中个体失去有效调节血液中葡萄糖水平的能力&#xff0c;并可能导致生活质量和预期寿命下降。。。。糖尿…

如何借助物联网实现土壤监测与保护

如何借助物联网实现土壤监测与保护 高标准农田信息化是指利用现代信息技术&#xff0c;如物联网、大数据、云计算等&#xff0c;对农田进行数字化、智能化的管理&#xff0c;以提高农田的生产效率和可持续发展能力。其中&#xff0c;土壤监测与保护是农田信息化的重要内容之一…

解决SD卡被写保护问题

存储卡在使用过程中&#xff0c;有时会遇到写保护问题&#xff0c;导致无法写入或删除数据。这可能会对用户的正常使用造成困扰。MK米客方德将为您介绍几种常见的解决方法&#xff0c;帮助用户解除存储卡的写保护。 一、检查物理写保护开关 许多存储卡&#xff0c;如SD卡&…

JavaScript的学习之dom的查询(一)

一、获得元素 通过document对象调用&#xff1a; getElementById()&#xff1a;通过id属性获取一个元素节点对象getElementsByTagName()&#xff1a;通过标签名获取一组元素节点对象getElementsByName()&#xff1a;通过name属性来获取一组元素节点对象 核心学习代码 <scrip…

【UE5.3】笔记3-静态网格体,BSP

静态网格体组件 主要有两个属性 一个是静态网格体&#xff1a;对应的也就是模型&#xff0c;比如fbx&#xff0c;maya&#xff0c;obj等格式 一个是材质&#xff1a;由各种贴图、渲染设置等&#xff0c;比如unity里的shader BSP画刷&#xff1a; 打开放置Actor选项卡&#…

QT中子工程的创建,以及如何在含有库的子工程项目中引用主项目中的qt资源

1、背景 在qt中创建多项目类型,如下: CustomDll表示其中的一个动态库子项目; CustomLib表示其中的一个静态库子项目; MyWidget表示主项目窗口(main函数所在项目); 2、qrc资源的共享 如何在CustomDll和CustomLib等子项目中也同样使用 MyWidget项目中的qrc资源呢??? 直…

MySQL 7种Join的定义图解示范结果(所有join类型)

文章目录 MySQL 7种Join的定义&图解&示范&结果&#xff08;所有join类型&#xff09;基本知识笛卡尔积 建表&填充数据1-Join不带条件account筛选 1-Inner Join 内连接不带条件account相同where筛选玩点特殊的 2-Left Join 左连接不带条件account筛选 3-Right J…

神经网络学习8-反向传播

back propagation 拿到前面传回来的L对z的偏导&#xff0c;再分别算损失值对x和w的偏导 反向传播 前馈过程求局部梯度 反向传播 这里的loss&#xff08;wxb-y)^2,第一个关于b的偏导为2(wxb-y),第二个关于w的为2w(wxb-y)

业绩尚可但股价不振,浙商银行陆建强闯“3元大关”

&#xff08;题图&#xff09; 文&#xff5c;新熔财经 作者&#xff5c;宏一 本来做着钱生钱的“美梦”&#xff0c;现在倒好&#xff0c;本金都不一定拿得回来。 因为不想把“鸡蛋都放在一个笼子里”&#xff0c;所以前几年在理财的时候一部分放在银行定存&#xff0c;一…

Sum of Single Effects Linear Regression (susieR):多个因果变异位点的鉴定

使用susieR鉴定多个因果变异位点只需要两个输入文件&#xff0c;一个输入文件是包含Zscore值的SNP位点&#xff08;zscore.txt&#xff09;&#xff0c;另一个文件是LD matrix&#xff08;LD.matrix.ld&#xff09;。 zscore.txt 文件如下所示&#xff1a; LD.matrix.ld 文件…

Vue DevTools

介绍 什么是 Vue DevTools&#xff1f; Vue DevTools 是一款旨在增强 Vue 开发者体验的工具&#xff0c;它是一款功能强大且用途广泛的工具&#xff0c;可以在使用 Vue 应用程序时显着提高您的生产力和调试能力。它的实时编辑、时间旅行调试和全面检查功能使其成为任何Vue.js开…

程序员如何用ChatGPT解决常见编程问题:实例解析

引言 在现代编程的世界中&#xff0c;技术进步日新月异&#xff0c;程序员们面临着各种各样的挑战和问题。解决这些问题的过程中&#xff0c;找到合适的工具至关重要。ChatGPT作为一种先进的人工智能语言模型&#xff0c;能够帮助程序员迅速、高效地解决常见的编程问题。本文将…

基于SpringBoot的学生综合测评系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot框架 工具&#xff1a;MyEclipse、Tomcat 系统展示 首页 系统首页&#xff0c;提供综合…

【ajax07基础】回调函数地狱

一&#xff1a;什么是回调函数地狱 在一个回调函数中嵌套另一个回调函数&#xff08;甚至一直嵌套下去&#xff09;&#xff0c;形成回调函数地狱 回调函数地狱存在问题&#xff1a; 可读性差异常捕获严重耦合性严重 // 1. 获取默认第一个省份的名字axios({url: http://hmaj…

LabVIEW电动汽车核心部件检测系统

LabVIEW开发的电动汽车核心部件检测系统&#xff0c;通过硬件接入板和数据采集卡实现信号采集和分析。系统具备智能诊断、模块化设计和用户友好的特点&#xff0c;能够快速、精确地定位故障&#xff0c;提高电动汽车的维护效率和可靠性&#xff0c;支持新能源汽车市场的快速发展…

【Streamlit学习笔记】Streamlit-ECharts箱型图添加均值和最值label

Streamlit-ECharts Streamlit-ECharts是一个Streamlit组件&#xff0c;用于在Python应用程序中展示ECharts图表。ECharts是一个由百度开发的JavaScript数据可视化库Apache ECharts 安装模块库 pip install streamlitpip install streamlit-echarts绘制箱型图展示 在基础箱型…