【Linux】进程状态的理解
✍作者:阿润菜菜
📖专栏:Liunx系统编程
本文目录
- 概述
- 两个先行概念
- 我们为啥创建进程
- Linux下的进程状态
- 1. R 运行状态
- 2.S 休眠状态 --- 可中断休眠状态
- 3. D 磁盘休眠状态 ---不可中断休眠
- 4.T 暂停状态 (t 追踪暂停状态)
- 5. X 死亡(瞬时)状态
- 6. Z 僵尸进程
概述
引入
其实在我们运行程序时,CPU并不是一个进程一直在运行,而是一个进程跑一会,另一个进程跑一会,这样间替周而复始。----- 分时操作系统
那凭什么要运行这个进程而不是另一个? 答案就取决于 进程状态
我们来看一下在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 */
};
可以看到状态态在kernel源代码里定义的方式大概是用一个数组包装,用不同的数字来标识不同的状态,如 0 代表R(运行)状态
- R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里
- S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))
- D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
- T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。注意还有个小写t 对应的是追踪暂停状态
- X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态
因为操作系统有很多,每个操作系统对进程的管理都有所差别,但基本原理是一样的,我们下面来研究Linux操作系统来观察进程状态
两个先行概念
阻塞:进程因为等待某种条件就绪,而导致的一种不推进的状态 ---- 进程卡住了 ---- 一定是在等待某种资源 ( 进程等待某种资源就绪的过程)
就比如我写了个scanf代码,当CPU运行到此处时,需要等待我从键盘进行输入,此时进程的状态就是阻塞状态。
为什么程序多会卡? 因为启动了太多的进程,操作系统难以调度过来,进程卡住了(阻塞!)
为什么要有阻塞? 进程要通过等待的方式,等具体的资源被别人用完之后,再被自己使用
挂起:闲置进程的代码和数据被交换到磁盘中(可以看作成一种特殊的阻塞状态)
注:
阻塞就是不被操作系统调度,一定是当前进程需要等待某种资源就绪,一定是task_struct结构体需要在被某种OS管理下的资源下进行排队
我们为啥创建进程
因为我们想要让进程帮我们办事情。进程给我们办事情我们就会关心结果,为了使程序能并发执行,且对并发执行的程序加以描述和控制(PCB),我们引出了进程的概念。
计算机在开机的时候,操作系统就会被加载到内存里面,磁盘中的程序在运行的时候也会被加载到内存里面,实际上是加载到操作系统内部,受操作系统的管理,我们知道程序运行的时候,是需要CPU进行读取进程的代码并计算的,但进程的数量一定会比CPU多,那CPU该怎么一个个的读取进程代码并计算呢?答案是通过运行队列(PCB数据结构)来对进程的运行进行管理。
Linux下的进程状态
我们可以通过测试代码进行观察
1. R 运行状态
1 #include <stdio.h>2 #include <unistd.h>3 #include <sys/types.h>4 5 int main()6 { 7 while(1) 8 {} 9 }
当程序代码只是一个死循环时,我们将程序运行起来,然后查看进程状态,可以很明显的看到状态是R,也就是运行状态。

,并不是CPU内维护。运行队列中是task_struct (PCB控制块)
2.S 休眠状态 — 可中断休眠状态
如果我们在刚刚代码中加入一句printf实现在显示屏上打印再来观察进程状态会出现什么?

结果

我们在代码中添加printf语句之后,程序还在运行,但观察到的进程的状态是S休眠状态,这是为什么呢?
因为我们的代码中访问了外设资源,即显示器。我们知道CPU会飞速的运行完进程的所有代码,但是我们写的进程需要占用硬件资源,每一次占用硬件资源都要等显示器就绪,这会花很长的时间(CPU计算的速度和IO的速度差别大概是几十万倍)。大概率99%的时间是进程在等显示器就绪,也就是在等待IO就绪,1%的时间是CPU在运行进程的代码,所以我们在查看进程状态的时候,极大概率上查到的都是S休眠状态。更形象化的说明就是,在进程访问完毕一次显示器的时候,CPU已经将这个死循环代码执行了50、60万次,所以我们在查看进程状态的时候,进程都是在等IO就绪的,所以就会查看到进程是休眠状态,这也是阻塞状态的一种。
S 休眠状态的两种
S 休眠状态本质是一种阻塞状态
S+: 前台运行 可以ctrl C暂停
S:后台运行 不可以Ctrl C暂停 可以直接kill 干掉
3. D 磁盘休眠状态 —不可中断休眠
S状态是浅度睡眠状态,是可以被终止的,通过ctrl+c或kill -9 pid两种方式进行分别进行前后台终止。
背景
当阻塞进程过多时,操作系统会将一些进程挂起,以此来解决内存空间不足的问题。如果挂起依旧无法解决内存空间不足,Linux操作系统就会将进程杀死,但是这样杀死进程很有可能导致进程对应的IO过程失败,从而丢失大量数据,这会对用户造成巨大的损失,所以就出现了一个新的进程状态,深度睡眠状态,这样的进具有无法被操作系统kill掉的特性。一般情况下,处于D状态的进程,只能等待IO过程结束,让进程自己醒来,重新投入CPU的运行队列,重新继续运行进程。或者万不得已可以通过断电的方式来杀掉深度睡眠的进程!!!
当然深度睡眠的状态一般不会出现,只有高IO的情况下,运行某个程序时,进程才有可能出现深度睡眠的状态。如果处于这种状态,计算机也宕机了。
4.T 暂停状态 (t 追踪暂停状态)
本质是阻塞状态的一种。
我们可以通过kill命令进行进程暂停状态的操作
kill -19 + 进程id --- 停止运行进程
kill -18 + 进程id --- 继续运行进程

注:状态后面带+,表示前台进程,状态后面不带+,表示后台进程
t 追踪暂停状态
Linux内核源代码中为了区分跟踪暂停和暂停状态,将T改为t来表示追踪暂停状态
适用在我们调试断点处 本质:暂停进程
当我们在调试某个二进制程序的时候,其实就是在调试该进程,当进程中有断点的时候,gdb中按下r进行调试运行,此时就会由于断点的存在而停下来,这其实表示的就是我们当前运行的进程停下来了,等待我们查看当前进程的上下文数据,这就是tracing stop状态,跟踪状态。
5. X 死亡(瞬时)状态
当进程结束时会显示X 状态,由于CPU处理的速度之快,我们极难观察到。
6. Z 僵尸进程
想一下如果一个进程退出了,立马进入X状态,你作为父进程,有没有机会拿到退出结果呢?
僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用,后面讲)
没有读取到子进程退出的返回代码时就会产生僵死(尸)进程。
所以Linux当进程退出的时候,一般进程不会立即彻底退出,而是要维持一个状态叫做:Z 僵尸状态。—方便后续父进程(OS)读取该子进程退出的退出结果。
只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态。
代码示例:
1 #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 5 int main()6 {7 8 pid_t id = fork();9 10 if (id==0)11 {12 printf("I am a child process,pid:%d,ppid:%d\n",getpid(),getppid());13 sleep(5);14 exit(1);15 }16 else17 {18 while(1)19 {20 printf("I am a parent process,pid:%d,ppid:%d\n",getpid(),getppid());21 sleep(1); 22 }23 }24 return 0;25 }
结果:

僵尸进程危害
那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!
进程的退出状态属于进程的基本信息,也是需要数据进行维护的,所以这种信息会被保存在进程对应的PCB里面,如果进程的状态一直是Z状态的话(父进程一直不读取子进程的退出状态),那么PCB就需要一直维护这种状态信息,虽然子进程对应的代码和数据会被释放,但是PCB是不会被释放的,因为他需要维护进程的Z状态,所以这个时候就会产生内存泄露的问题
僵尸进程无法被杀掉,即使通过kill信号也无法杀掉,因为它已经死亡了,所以无法被杀掉的进程有三个,深度睡眠进程,僵尸进程,死亡进程,D状态是不能杀,Z和X是无法杀,因为已经死了! 😳
在结束进程之后,操作系统拿到退出码,进行甄别帮我们将父进程和子进程一起回收掉。以免内存泄露的发生。
相关文章:
【Linux】进程状态的理解
✍作者:阿润菜菜 📖专栏:Liunx系统编程 本文目录概述两个先行概念我们为啥创建进程Linux下的进程状态1. R 运行状态2.S 休眠状态 --- 可中断休眠状态3. D 磁盘休眠状态 ---不可中断休眠4.T 暂停状态 (t 追踪暂停状态)5…...
打游戏哪种蓝牙耳机比较好?适合玩游戏的无线蓝牙耳机
2023年耳机市场一如既往地卷,不只是卷音质,还在外观和功能上做了许多的改进,以至于现在哪怕不懂耳机的人从各电商平台都能闭眼入一个款平价品牌耳机且极少会踩雷,玩游戏是当前年轻人的娱乐方式,下面整理了几款适合玩游…...
Fortinet推出新一代自研安全芯片,跨所有网络边缘加速网络与安全融合
专注网络与安全融合的全球网络安全领导者 Fortinet(NASDAQ:FTNT),近日宣布推出新一代自研安全芯片 FortiSP5,作为 Fortinet ASIC 技术的最新突破,有力推动了分布式网络边缘安全的重大飞跃。FortiSP5 源自 F…...
ChatGPT爆火背后的真相:学编程已经成为必选项
这一阵最热门的话题,莫过于人工智能新选手——ChatGPT,在推出后只用了两个月就积累了1亿用户!它的出现在科技圈掀起了一阵“惊涛骇浪”,有人称ChatGPT的意义,堪比当年蒸汽机的出现,它足以爆发新一轮的“工业…...
Unity UI框架
一、简介 最近在各大网站看了一下 Unity3d 的 UI 框架,各种 UI 框架已经有很多的版本了,各有千秋,有的功能虽然写的完善,但用起来太复杂,有的框架功能不完善,搞个课程就上架了,还有什么 MVC 框…...
vue2提取vue-router的title单独存放,使用i18n实现
成品效果 首先引入i18n(vue-i18n官网文档) 依赖包 npm install vue-i18n8然后单独在src目录下新建一个文件夹lang,存放相对应的变量名称,我这里只做显示中文所以其他引入我都注释了,具体目录如下: src\lang/zh.js部分代码 export…...
【Linux操作系统】【综合实验三 用户帐号、文件系统与系统安全管理】
文章目录一、实验目的二、实验要求三、实验内容四、实验报告要求一、实验目的 要求掌握Linux系统用户的创建、删除与管理操作;熟悉Linux文件系统的管理模式,学会创建用户文件系统并装载和卸载文件系统;掌握超级用户的管理方式与权限…...
sqlite3数据库-sqlite语句1(五)
DML(Data Manipulation Language,数据操作语言) SELECT:查询表中的数据;SELECT语句中使用WHERE子句SELECT <列名>,... FROM <表名> WHERE <条件表达式>;SELECT id,name,purchase_price FROM Product; /*使用逗号分隔查询多列,顺序同子句顺序*/ SELECT * FROM…...
【图像分类】卷积神经网络之LeNet5网络模型实现MNIST手写数字识别
写在前面: 首先感谢兄弟们的关注和订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 在上一篇博文中我们对LeNet5网络模型的结构进行了剖析,本篇博文,我们将使用PyTorch搭建LeNet5实现MNIST手写数字…...
前端开发环境搭建
文章目录Node.js是什么安装查看版本入门示例NPM使用 npm 命令安装模块常见命令使用淘宝 NPM 镜像TypeScript安装入门示例从github拉取构建项目如何从零创建一个TypeScript项目规划目录结构新建项目Web App运行服务添加依赖打包使用browserify打包使用webpack打包推荐流程目录配…...
学习Flask之四、网页表单
第二章介绍的request对象,使用了客户端请求的所有信息。特别地,request.form提供了对POST请求提交的表单数据的访问。尽管Flask请求对象的支持足于处理网页单,但是还有很多作务很繁锁和重复。两个很好的例子是产生HTML表单代码和验证表单数据…...
CenterMask paper笔记
CenterMask是一个anchor free的实例分割模型, 来自paper: CenterMask: Real-Time Anchor-Free Instance Segmentation 提起anchor free, 会想到FCOS模型,是用来目标检测的, 那么这里就用到了FCOS, 不过换了backbone, 在FCOS检测出目标框后&…...
06- OpenCV查找图像轮廓 (OpenCV基础) (机器视觉)
知识重点 灰度图转换: gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)二值化: 返回两个东西,一个阈值, 一个是二值化的图: thresh, binary cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)查找轮廓: 返回两个结果,分别是轮廓和层级: c…...
OpenGL学习日记之模型绘制
自己编译运行过程中遇到的一些问题 下载Assimp已编译的lib(因为我们公司的电脑有很多权限和限制,也不能自己安装一些没有报备的软件,所以愁方便我就没有用cMake自己编译了)找到一位免费分享的博主的。 https://blog.csdn.net/lady_killer9/article/deta…...
Springboot接口多个DTO入参的Postman上传方式
在Java中使用Spring Boot框架时,可以同时使用多个DTO作为方法参数。 TO(Data Transfer Object)是一个常见的设计模式,用于封装数据传输对象。它通常用于将数据从一个层传递到另一个层,例如将数据从服务层传递到控制器…...
软考各科目考核内容详细介绍,看这里
新手在准备报考软考时,都会遇到这样的一个问题——科目这么多,我适合考什么?要想知道自己适合报什么科目,就需要了解每个科目是什么,考什么等一系列的问题。 接下来,就为大家介绍一下软考的各个科目&#…...
连续时间信号与离散时间信号
前言 《信号与系统》是一门很难的课,也是许多学校考研要考的专业课,由于每周只有两节课,所以每次上完都要及时的去复习,这里参考的教材是奥本海姆著作,刘海棠译,北京:电子工业出版社࿰…...
TPM密钥管理、使用
前面讲过证书相关内容,除了在软件方面有所应用外,在硬件方面也有很多应用。本次讲一下TPM相关的内容。 一、TPM介绍 1.1背景 TCG基于硬件安全的架构是为应对1990s后期日益增多的复杂恶意软件攻击应用而生的。当时以及现在,抵御PC客户端网络…...
return和finally执行顺序、运行时异常与一般异常异同、error和exception区别、Java异常处理机制原理与应用
文章目录1.try {}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?2.运行时异常与一般异常有何异同?3.java 程序中的错误有三种类型分别是什么4.error和exception有什么…...
我为什么放弃WinUI3
基于WinUI3开发HiNote已经有一个多月的时间了,算是做出来一个简单能用的C端软件。 基于个人的经历,说说其中的开发体验。 UI设计语言 无论是否抄袭苹果,WinUI3给人的感觉都是眼前一亮的。简洁美观,现代化,毛玻璃的美…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
