【Linux】进程状态(RSDT 阻塞 僵尸 孤儿)

目录

进程状态

进程状态的查看

R和S 运行状态

T/t 暂停状态

kill命令

D (disk sleep)状态、

Z 状态(僵尸状态)

孤儿状态

运行状态

阻塞状态


 

进程状态

一个进程通常有三种状态

就绪状态(Ready):表示进程已经具备运行所需要的一切条件,只需要等待CPU的分配就可以运行。进程处于就绪状态时,通常会被添加到就绪队列,等待调度器分配CPU资源。

运行状态(Running):表示进程正在被CPU执行。处于运行状态的进程正在使用CPU进行计算或其他操作。

阻塞状态(Blocked):表示进程因为某些原因暂时无法继续执行,需要等待一些特定条件的解除之后才能继续运行。例如,当进程等待I/O操作完成或者等待某个资源可用时,会转入阻塞状态。进程在阻塞状态时,通常会被移动到阻塞队列中,等待条件的满足

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

下面的状态在Kernel源代码里定义:

 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 */
};

 

进程状态实质是结构体task_struct内部的一个属性。通过宏定义的方式进行描述以及更改进程状态

#define RUN 1
#define SLEEP 2  
#define STOP 3struct task_struct
{// 内部的一个属性int status;
}struct task_struct process1; //创建进程
process1.status=RUN;//设置进程状态

进程状态的查看

 while :; do ps axj | head -1 && ps axj | grep testStatus | grep -v grep; sleep 1;done 

R和S 运行状态

❍ R运行状态(running):并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。

❍ S睡眠状态(sleeping)意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠)

通过C语言代码进行验证,依旧使用makefile工具

makefile代码:

bin=testStatus
src=testStatus.c
$(bin):$(src)gcc -o $@ $^ -std=c99
.PHONY:clean
clean:rm -f $(bin)

testStatus.c代码:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>int main()
{while (1){printf("I am a process,pid: %d\n", getpid());}return 0;
}

通过运行结果我们i可以看到,我们的进程一直在运行,但是进程状态是S+状态,也就是休眠状态,可是按照我们自己的理解,程序正在运行不应该是R(运行状态)吗?为什么这里是S+状态呢?

这是因为:printf的本质是往显示器上进行打印;而程序的运行是在千里之外的云服务器上的,最终打印出来的信息显示到我们本地的显示器上;根据冯诺依曼体系结构,显示器是一个外设,所以CPU在跑当前的程序时,把数据写入到我们当前的内存中,打印数据的顺序:先写入到内存里,再刷新到外设这里。可是我们无法保证每次打印的时候,显示器的状态都是就绪的,因为程序是CPU跑的,CPU的运算速度要比显示器本身的速度要快的多,这种快慢人是无法感知的,所以进程在被调度的时候,要访问显示器的资源,因为资源要一直在显示器上打,所以大部分时间,我们的进程一直在等待我们的设备资源是否准备就绪。所以也就是为什么总是S(休眠状态)

注意: 

./testStatus & # 在执行可执行程序后面加&符号,为在后台运行,跑起来后面不带+号。+号表示在前台还是后台运行,以什么为参考系后面说。后台运行后面有数字(pid),且ctrl +c 不能中断进程,需用kill -9 pid杀掉进程。

T/t 暂停状态

kill命令
	kill  [-s <信号名称或者编号>][程序]   或   kill  [-l <信息编号>]

功能:给指定命令发信号

常见选项:-l <信息编号> : 若不加<信息编号>选项,则 -l 参数会列出全部的信息名称。

总共有64个信息编号,其实上面的这些东西都是宏,我们已经会使用 -9 杀死进程,下面我们会用到 -18(SIGCONT)进程继续 以及 -19(SIGSTOP)暂停进程

一个进程被暂停也会自动变为后台(只能使用kill -9杀死进程)

 上面运行的是T状态,接下来我们来看 t 状态

❍ t (tracing stop) : 当前的进程因为被追踪而暂停了

这种情况可以在调试代码的时候遇见,因为调试的过程,中间就有暂停的动作

D (disk sleep)状态、

❍ D (disk sleep): Linux系统比较特有的一种进程状态,不可被杀,深度睡眠,不可中断睡眠

◉ 一个进程要将1个G的数据存储到磁盘,根据冯诺依曼体系结构可以知道,本质是把数据从内存交给外设,由于速度差,进程需要等待硬盘资源把数据写入完毕,此时进程处于S状态,又因为操作系统管理进程,当系统整个的内存资源严重不足时Linux操作系统有权利杀掉进程来释放空间,然后操作系统把A进程杀掉,但是此时B进程要给硬盘写入数据,硬盘需要去照顾B进程,导致A进程写入数据失败了,1GB的数据丢失了,如果这个数据是银行的转账记录,那么可能造成很大的影响。

◉ 为了避免这种情况,如果进程在等待硬盘资源时,进程需要将自己的状态设为D状态:不可被杀深度睡眠,不可中断睡眠。

◉ 我们一般不会遇到这种情况,从事系统管理、运维、存储等工作可能会遇到。

 

杀死D状态的方法:

1️⃣ 让进程自己醒来

2️⃣ 重启,重启不行则断电

Z 状态(僵尸状态)

僵尸状态:当一个 Linux 中的进程退出的时候,一般不会直接进入 X 状态(死亡,资源可以立马被回收),而是进入 Z 状态。如果父进程不对其进行回收,则会一直处于僵尸状态,也就是子进程先于父进程退出

就好比如:在杀人案中,一名尸体躺在地下,这时候你发现了,你连忙开始报警,报警后,警察来的第一件事不是移走尸体,而是进行封锁现场,让尸体原地待着,等待法医进行检验后,再进行移动。在这个让尸体原地待着的过程,就是Z状态,僵尸状态

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

#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(15); // 父进程延迟回收子进程}return 0;
}

为什么父进程不回收子进程PCB?

1.父进程要知道子进程为什么要退出,父进程要获取子进程退出的信息。

2.独立性,父进程只读取子进程的信息,不对信息做修改,依旧保持独立性。

僵尸进程的危害

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

避免僵尸进程

可以通过以下方式:

1️⃣ 父进程及时调用wait()waitpid()回收子进程。

2️⃣ 使用信号处理机制,在子进程退出时通知父进程进行回收。

孤儿状态

孤儿进程:即父进程不是休眠,而是比子进程提前结束,造成子进程不归原父亲管理,原子进程父亲变为1号进程,相当于被OS领养了

测试代码:

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

 

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

◉ 那是因为父进程的父进程是bash ,它会自动回收它的子进程,也就是这里的父进程。这里之所以没有看到父进程变成僵尸,是因为被 bash 回收了, z->x 的状态很快,所以你没看到。 ​

◉ 那为什么刚才我自己代码中的父进程创建的子进程,父进程没有回收子进程呢?那是因为你的代码压根就没有写回收,所以你的子进程就没有回收。

并且这里我们也发现 子进程由 S+ -- > S,此刻退出子进程也必须使用kill - 9;

运行状态

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

每个task_struct对应一个时间片,当执行程序时间到了之后,会自动切换到下一个进程,也就是CPU的执行是基于时间片进行轮转调度的,在一个时间段内同时得以推进代码,就叫做并发

如果我们不止一个CPU,那么任何时刻,都同时有多个进程在真的同时运行,我们叫做并行

 

阻塞状态

在操作系统中,阻塞状态(Blocked State)是进程生命周期中的一个状态,当进程等待某些事件发生而无法继续执行时,它就会进入阻塞状态。

关于进程: ① 一个进程使用资源的时候,可不仅仅是在申请 CPU 资源 ② 进程可能会申请其它资源:磁盘、网卡、显卡,显示器资源…… 如果我们申请 CPU 资源无法暂时无法得到满足,这就需要排队的 "运行队列" 。那么如果我们申请其他慢设备的资源呢?是需要排队的(task_struct 在进程排队)。

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

① 当前进程要从 runqueue 中逐出。

② 将当前进程放入对应设备的描述结构体中的waitqueue 。

注意:并不是只有等待硬件资源的进程才处于阻塞状态,一个进程等待另一个进程就绪、一个进程等待软件资源就绪等也是阻塞状态。

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

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

相关文章

如何验证谷歌seo服务商的实力真假?

要验证谷歌SEO服务商的实力真假&#xff0c;可以通过几种简单有效的方法。 你可以要求对方通过视频会议或上门服务&#xff0c;展示谷歌官方后台的真实数据。 通过Google Search Console的实时数据&#xff0c;你可以直接看到他们为客户提供的服务效果&#xff0c;这样的数据是…

【加密社】如何根据.dat文件恢复密钥

加密社 看了这篇指南&#xff0c;你将了解助记词和密钥地址&#xff08;qianbao&#xff09;背后的基本原理。 以及&#xff0c;如何找回你的大饼密钥。 Not your key, not your coin 如果你不掌握自己加密货币钱包的私钥&#xff0c;那么你实际上并不能完全控制你的资产 在当今…

【STM32开发笔记】STM32H7S78-DK上的CoreMark移植和优化--兼记STM32上的printf重定向实现及常见问题解决

【STM32开发笔记】STM32H7S78-DK上的CoreMark移植和优化--兼记STM32上的printf重定向实现及常见问题解决 一、CoreMark简介二、创建CubeMX项目2.1 选择MCU2.2 配置CPU时钟2.3 配置串口功能2.4 配置LED引脚2.5 生成CMake项目 三、基础功能支持3.1 支持记录耗时3.2 支持printf输出…

基于FPGA的OV5640摄像头图像采集

1.OV5640简介 OV5640是OV&#xff08;OmniVision&#xff09;公司推出的一款CMOS图像传感器&#xff0c;实际感光阵列为&#xff1a;2592 x 1944&#xff08;即500w像素&#xff09;&#xff0c;该传感器内部集成了图像出炉的电路&#xff0c;包括自动曝光控制&#xff08;AEC…

内网渗透-域环境搭建

构建内网环境 在学习内网渗透测试时,需要构建一个内网环境并搭建攻击主机,通过具体操作理解漏洞的工作原理,从而采取相应的防范措施。 一个完整的内网环境,需要各种应用程序、操作系统和网络设备,可能比较复杂。我们只需要搭建其中的核心部分,也就是Linux服务器和 Windows服务…

复变函数在大模型中的应用

1. 导入 说来惭愧&#xff0c;我研究生时的研究方向是复分析&#xff0c;但毕业近十年来几乎没用到它。 我还记得实习时做自我介绍时&#xff0c;我说我的研究方向是复分析。面试官不太了解&#xff0c;我便解释说&#xff0c;这是关于对 -1 开平方得到的虚数 i 的研究。 在…

【iOS】——分类拓展关联对象

分类 OC的动态特征允许使用类别为现有的类添加新方法并且不需要创建子类&#xff0c;不需要访问原有类的源代码。通过使用类别即可动态为现有的类添加新方法&#xff0c;而且可以将类定义模块化分布到多个相关文件。 分类是 Objective-C 中的一种语言特性&#xff0c;它允许你…

缓解webclient频繁报‘Connection prematurely closed BEFORE response’的问题

现象&#xff1a; 我在Java代码中使用org.springframework.web.reactive.function.client.WebClient进行网络请求&#xff0c;一开始会有比较多的偶发报错&#xff1a;Connection prematurely closed BEFORE response&#xff0c;网络连接莫名其妙就断了。 处理&#xff1a; …

pm2 + linux + nginx

pm2 pm2是一个用于管理node项目的工具 前言 有如下两个文件 index.js const express require("express"); const app express(); const port 9999;app.get("/index", (req, res) > {res.json({code:200,msg:"songzx001"}) });app.lis…

学习硬件测试06:IIC(SHT30)+HMI串口屏+RS485(modbus)+SPI Flash读写+CAN通信(P81、P91、P95、P120、)

文章以下内容全部为硬件相关知识&#xff0c;鲜有软件知识&#xff0c;并且记的是自己需要的部分&#xff0c;大家可能看不明白。 一、IIC&#xff08;SHT30 数字温湿度传感器&#xff09; 1.1实验现象 1、软件模拟 I2C 协议与 SHT30 数字温湿度传感器通讯&#xff1b; &am…

怎么把视频转换成mp4:好用的mp4格式转换器免费版推荐

用手机或者其他拍摄设备记录生活已经成为一种日常&#xff0c;当你想把手机里储存的日常小确幸发布到平台上时&#xff0c;才发现你视频的格式在平台上并不被支持。这个事实难免让人丧气。如果你还想继续上传视频的话&#xff0c;就不得不把视频格式转换成被平台支持的mp4格式。…

ELK系列之一---探索ELK奇妙世界:初识日志界大名鼎鼎的ES集群!

目录 一、为什么要使用ELK 二、ELK简介 三、Elaticsearch入门 3.1、什么是elaticsearch 3.2、elaticsearch的底层优点 3.2.1、全文检索 3.2.2、倒排索引 3.3、elaticsearch集群原理 一、为什么要使用ELK 一般我们需要进行日志分析场景&#xff1a;直接在日志文件中 gre…

Redis从入门到入门(上)

1.Redis概述 文章目录 1.Redis概述1.1 什么是Redis1.2 Redis的应用场景 2.Linux下Redis的安装与使用2.1 Redis下载2.2 Redis的启动2.3 Redis配置2.4 连接Redis 1.1 什么是Redis Redis是用C语言开发的一个开源的高性能键值对&#xff08;key-value&#xff09;数据库&#xff0…

C语言sprintf函数使用

1 其函数原型为&#xff1a;int sprintf(char *str, const char *format,...)。 具体用法如下&#xff1a; 基本语法&#xff1a; str&#xff1a;目标字符串的指针&#xff0c;用于存储格式化后的结果。format&#xff1a;格式化字符串&#xff0c;用于指定输出的格式。后续是…

数据结构-队列的介绍及循环队列

1.队列的概念 在开始前&#xff0c;请牢记这句话&#xff1a;队列是一个先进先出的数据结构。 队列&#xff08;queue&#xff09;是限定在表的一端进行插入&#xff0c;表的另一端进行删除的数据结构&#xff0c;如同栈的学习&#xff0c;请联系前文所学链表&#xff0c;试想…

4.5SQL注入之加解密注入

SQL注入之加解密注入Base64是网络上最常见的用于传输8Bit字节码的编码方式之一&#xff0c;Base64就是一种基于64个可打印字符来表示二进制数据的方法。 Less-21关 Cookie加密注入&#xff1a; 通过Burpsuite抓包&#xff1a; 进行Base64解密&#xff1a;

波场(Tron)监听区块交易(TRX,USDT)

前言说明&#xff1a; 本篇文章参考GitHub一位伙伴的代码&#xff0c;再代码基础上优化改良以后的结果&#xff0c;但是一下找不到那位大佬的GitHub链接了&#xff0c;如有侵权请联系作者调整文章&#xff0c;让跟多人收益。谢谢。 实现思路: 波场链是一条很新奇的链&#xff…

Nexus配置npm私服

1&#xff0c;配置npm-hub 2&#xff0c;配置proxy-npm 3&#xff0c;配置group-npm 4&#xff0c;配置local-npm 5&#xff0c;配置淘宝

[overleaf] 论文中含有中文字符导致编译失败

解决方案分为两步&#xff1a; 1. 加入package&#xff1a; UTF8或者xeCJK \usepackage[UTF8]{ctex}二选一 \usepackage{xeCJK} 2. 修改编译方式&#xff1a; Menu -> Setting -> Compiler -> XeLatex

MyPrint打印设计器(七)svg篇-二阶贝塞尔曲线

svg-二阶贝塞尔曲线 介绍一款强大的svg操作库&#xff0c;能够通过简单的代码&#xff0c;实现svg绘制与操纵&#xff0c;实现拖拽等功能 代码仓库 在线体验 代码仓库&#xff1a;github 代码仓库&#xff1a;gitee 实战项目&#xff1a;MyPrint 操作简单&#xff0c;组件丰富…