【Linux】LInux下的进程状态

在这里插入图片描述

👦个人主页:Weraphael
✍🏻作者简介:目前正在学习c++和算法
✈️专栏:Linux
🐋 希望大家多多支持,咱一起进步!😁
如果文章有啥瑕疵,希望大佬指点一二
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注😍


目录

  • 一、进程状态
  • 二、Linux操作系统下的进程状态
      • 2.1 进程状态在kernel源代码的定义
      • 2.2 运行状态 R
      • 2.3 浅度睡眠状态 S
      • 2.4 磁盘休眠状态 D
      • 2.5 停止状态 T
      • 2.6 追踪状态 t
      • 2.7 死亡状态 X
      • 2.8 僵尸状态(僵尸进程) Z
  • 三、孤儿进程
  • 四、代码

一、进程状态

进程状态通常是通过进程控制块PCB对象来管理和维护的。它记录了进程当前所处的状态,比如就绪、运行、阻塞等等。当进程状态发生变化时(比如由就绪变为运行),操作系统会更新 PCB 中对应的状态字段。使得操作系统能够有效地管理进程,进行进程调度、资源分配等操作。

以下是六个常见的进程状态:

在这里插入图片描述

  • 新建态:可以理解为操作系统正在为某个进程创建进程控制块PCB对象的过程。(PCB:操作系统用来管理和跟踪进程信息的数据结构,可以理解为描述进程属性的集合)
  • 就绪态:进程在就绪队列里已经准备好运行,等待被调度到CPU上执行。将其调度到运行态。(调度:从就绪队列中选择一个进程,并将其分配给CPU执行。调度器的目标是优化系统性能、资源利用率和响应时间,以满足用户需求或系统的指定策略。)
  • 运行态:进程正在CPU上执行指令。但进程的运行状态通常是暂时的,一旦一个进程的时间片段用完,或者发生某些事件(比如等待I/O操作完成),它可能会被操作系统调度到阻塞状态,等待一定条件满足后重新进入就绪状态。(时间片:在多进程的操作系统中,由于CPU是有限的。为了公平地分配CPU时间给各个进程,操作系统采用了时间片轮转调度算法。当时间片用完后,操作系统会剥夺当前进程的CPU控制权,并将其放回就绪队列,然后选择下一个就绪状态的进程给予CPU时间片,如此循环执行。)
  • 阻塞态:进程由于某些原因(比如等待I/O操作完成或者等待某个事件发生)而暂时无法继续执行,进入阻塞状态。阻塞态的进程通常会放置在阻塞队列中,等待某些条件满足(比如等待I/O操作完成)后重新进入就绪态。
  • 终止态:进程已经执行完成,或者被操作系统终止。
  • 挂起态:当一个进程长时间被阻塞时,如果不再占用CPU和其他系统资源时,进程会被挂起,操作系统通常会保留进程的PCB在内存中,并可能通过交换将部份进程的代码和数据移动到磁盘上的交换空间中,以释放内存。等待相应的事件发生后再次被唤醒执行。

二、Linux操作系统下的进程状态

2.1 进程状态在kernel源代码的定义

/*
* 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)", # 运行状态
"S (sleeping)", # 睡眠状态
"D (disk sleep)", # 磁盘休眠状态
"T (stopped)", # 停止状态
"t (tracing stop)", # 进程正在被追踪
"X (dead)", # 死亡状态
"Z (zombie)", # 僵死状态
};

2.2 运行状态 R

Linux中,运行状态并不意味着进程一定在运行中,只要满足进程是在运行中或者在运行队列里就称此进程时运行状态(运行态 + 就绪态)。

以下面代码为例,来查看当代码运行起来是否为运行状态

在这里插入图片描述

要查看Linux的进程状态可以使用以下命令

ps ajx | head -1 && ps ajx | grep 'proc' | grep -v 'grep'

在这里插入图片描述

其中,+代表的是该进程是前台运行

  • 当进程以前台方式运行时,它会将输出结果直接发送到终端,并且它的执行会阻塞终端的使用。用户可以通过在终端按下ctrl + c或者使用kill命令可以向进程发送信号9SIGKILL)终止前台运行的进程。
kill -9 PID

在这里插入图片描述

  • 当进程以后台方式运行时,它不会占用终端并且不会阻塞用户的输入输出。用户可以通过在命令末尾添加&符号来将进程置于后台运行。但如果想杀掉进程只能用kill命令。
    在这里插入图片描述

2.3 浅度睡眠状态 S

浅度睡眠状态本质上就是阻塞状态。

等待I/O操作是一个经典的阻塞状态

在这里插入图片描述

查看进程状态

ps ajx | head -1 && ps ajx | grep 'proc' | grep -v 'grep'

在这里插入图片描述

除此之外,bash命令行也是一个非常经典的浅度睡眠状态(阻塞状态),因为它需要等待用户输入指令与操作系统交互。

在这里插入图片描述

  • S:表示进程处于睡眠状态

  • s:表示进程是会话的领头进程。

  • Ss:既处于睡眠状态,又是会话的领头进程(系统第一个用户级别进程)。

2.4 磁盘休眠状态 D

磁盘休眠状态也称深度睡眠状态,它其实也是一种阻塞状态。

比如一个进程需要向磁盘写入数据,由于向磁盘写入数据很慢,那么此时进程必定会进入长时间的等待!而内存的资源是有限的,那么极端情况下,操作系统就可能会将该进程杀死(Linux操作系统会在内存不足时进行杀进程),那么就会导致数据丢失。因此我们只需让进程在等待磁盘写入完毕期间不被任何人(包括操作系统)杀掉即可,这就是深度睡眠状态(不响应任何请求)。

如果进程长时间处于休眠状态,特别是在等待同一种事件(比如磁盘IO)时,这可能是系统出现问题的迹象之一。这可能意味着系统资源被耗尽,导致无法满足进程的需求,从而导致系统性能下降甚至宕机。

终止休眠进程的一个方法就是切断电源,此时进程是结束了,但整个系统也结束了。

2.5 停止状态 T

顾名思义就是停止当前进程

我们可以通过kill发送信号来停止进程或者继续运行某个进程。首先通过一下指令列出kill命令下的所有信号

kill -l

在这里插入图片描述

以下面示例代码为例,当代码运行起来时会进入死循环状态

在这里插入图片描述

接下来使用以下命令停止进程并查看进程状态

kill -19 PID

在这里插入图片描述

我们发现进程确实暂停了,但现在我们又想要让进程运行起来

kill -18 PID

在这里插入图片描述

cout的打印操作可能会被阻塞,因为它需要与显示器设备进行交互,并且显示器设备可能不一定处于可以立即接受写入数据的状态。

  • 显示器设备缓冲区已满: 如果显示器设备的缓冲区已满,而cout尝试向其写入数据,那么cout的打印操作可能会被阻塞,直到缓冲区中有足够的空间来接受新的数据。
  • 显示器设备正在执行其他操作: 如果显示器设备正在执行某些其他操作,例如刷新屏幕、处理其他输入,那么cout的打印操作可能会被阻塞,直到设备空闲下来可以接受新的数据。

2.6 追踪状态 t

追踪状态也是暂停状态的一种。

当我们用gdb调试我们代码时,运行至断点时便处于此种状态

在这里插入图片描述

2.7 死亡状态 X

本质上就是终止态:进程已经执行完成,或者被操作系统终止。你不会在进程列表里看到这个状态。

2.8 僵尸状态(僵尸进程) Z

Linux中,一个进程终止了不会立马进入死亡状态。而是会先进入僵尸状态。僵尸状态是指子进程已经终止执行,但其相关的进程控制块PCB和资源仍然保留在系统中,直到其父进程获取子进程终止状态(获取方式:waitpid),子进程才能释放资源,变为死亡状态;如果父进程没有及时处理,这个进程就会变成僵尸进程。

以下面代码为例,子进程提前终止,父进程继续执行cout语句

void exit(int status)

当调用exit函数时,当前进程会立即停止执行,并返回给其父进程一个终止状态status,表示进程的退出状态。这个终止状态可以在父进程中通过调用waitpid来获取。

在这里插入图片描述

接下来查看进程状态

ps ajx | head -1 && ps ajx | grep 'proc' | grep -v 'grep'

在这里插入图片描述

通过观察我们发现子进程处于僵尸状态,因为父进程一直没有获取子进程的退出状态,于是子进程要一直维持僵尸状态。而一直维持僵尸状态,那么相关的进程控制块PCB和资源仍然保留在系统,那势必就会引发内存泄漏

三、孤儿进程

Linux当中的进程关系大多数是父子关系,若子进程先退出并且父进程没有对子进程的退出信息进行读取,那么我们称该进程为僵尸进程。

父进程如果提前退出,那么子进程后退出,进入僵尸状态之后,那该如何处理呢?

例如,对于以下代码,fork函数创建的子进程会一直打印信息,而父进程在打印3次信息后会退出

在这里插入图片描述

运行结果如下:

在这里插入图片描述

观察代码运行结果,在父进程未退出时,子进程的PPID就是父进程的PID,而当父进程提前退出后,子进程的PPID就变成了1,即子进程被1号进程(操作系统)领养了。

【总结】

  • 若是父进程先退出,那么将来子进程进入僵尸状态时就没有父进程对其进行处理,此时该子进程就称之为孤儿进程。
  • 如果父进程一直不获取子进程终止状态,那么孤儿进程就会一直占用资源,此时就会造成内存泄漏。因此,当出现孤儿进程的时候,孤儿进程会被1号进程(操作系统)领养,此后当孤儿进程进入僵尸状态时就由1号进程自动回收。

四、代码

本篇博客相关代码:点击跳转

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

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

相关文章

APP UI自动化测试,思路全总结在这里了

首先想要说明一下,APP自动化测试可能很多公司不用,但也是大部分自动化测试工程师、高级测试工程师岗位招聘信息上要求的,所以为了更好的待遇,我们还是需要花时间去掌握的,毕竟谁也不会跟钱过不去。 接下来&#xff0c…

新书速览|数字身份认证技术与实践

本书不仅仅讲述标准解决方案以及相关理论,更重要的是以丰富的案例,讲透如何将这些理论应用到具体实际场景。 本书内容 《数字身份认证技术与实践》内容涵盖身份认证的基础理论,包括身份认证与授权的区别、常见的认证方式以及关键技术和协议&…

代码随想录算法训练营33期 第五十天 | 188.买卖股票的最佳时机IV

dp[i][0] 不操作;d[i][1]第一次开始持有股票 //dp[i]当前天i的价值情况,dp[i][0]表示不操作的最大价值,dp[i][1]在当前天第一次持有的最大价值,dp[i][2]在当前天第一次卖出的最大价值, dp[i][3]在当前天第二次持有的最大价值&am…

苍穹外卖学习笔记(8.用户端历史订单模块,商家端订单管理模块)

目录 一、商家端订单管理模块1、查看历史订单2、查询订单详情3、取消订单4、再来一单5、代码开发6、测试 二、用户端历史订单模块1、订单搜索2、各个状态的订单数量统计3、查询订单详情4、接单5、拒单6、取消订单7、派送订单8、完成订单9、代码开发10、测试 三、校验收货地址是…

matlab学习005-利用matlab设计滤波器

目录 一,含有多个频率成分的三角信号 1,以采样频率fs20KHz对信号采样, 画出信号的波形; 1)前期基础 2)波形图 3)代码 2,选取合适的采样点数,利用DFT分析信号的…

Python静态资源库之webassets使用详解

概要 Python webassets库是一个用于管理静态资源的工具,如CSS、JavaScript等,帮助开发者更有效地管理和优化网站的静态文件。本文将介绍如何安装和使用Python webassets库,以及它的特性、基本功能、高级功能、实际应用场景和总结部分。 安装 首先,需要安装Python webasse…

Mysql索引详解(索引分类)

文章目录 概述索引对查询速度的影响索引的优缺点索引类型一级索引和二级索引的区别MySQL 回表联合索引(最左前缀原则主键索引和唯一索引的区别BTree索引和Hash索引的区别 覆盖索引索引下推加索引能够提升查询效率原因MySQL 索引结构采用 B树原因索引失效的场景MySQL…

知识图谱嵌入领域的重要研究:编辑基于语言模型的知识图谱嵌入

今天,向大家介绍一篇在知识图谱嵌入领域具有重要意义的研究论文——Editing Language Model-based Knowledge Graph Embeddings。这项工作由浙江大学和腾讯公司的研究人员联合完成,为我们在动态更新知识图谱嵌入方面提供了新的视角和方法。 研究背景 在…

kubernetes中的附件组件Metrics-server与hpa资源实现对pod的自动扩容和缩容

一、概述 Metrics-Server组件目的:获取集群中pod、节点等负载信息; hpa资源目的:通过metrics-server获取的pod负载信息,自动伸缩创建pod; 二、安装部署 Metrics-Server组件 安装目的,就是给k8s集群安装top…

Win 下 ncnn 编译运行

ncnn 官网上编译的过程比较详细,本文主要记录编译、运行过程中遇到的问题,希望可以帮到大家。 我的环境是 Win10 系统,VS 2022。 编译 先使用如下命令获取 ncnn 代码库: git clone https://github.com/Tencent/ncnn.git cd n…

【库函数】Linux下动态库.so和静态库.a的生成和使用

目录 🌞1. Linux下静态库和动态库的基本概念 🌞2. 动态库 🌊2.1 动态库如何生成 🌍2.1.1 文件详情 🌍2.1.2 编译生成动态库 🌊2.2 动态库如何使用 🌍2.2.1 案例 🌍2.2.2 动态…

速卖通自养号测评:如何规避安全风险?

对于初涉电商领域的新卖家而言,进行销量测评显得尤为关键。由于速卖通新店铺往往难以获得平台活动的支持,流量也相对匮乏,因此,开店的首要任务便是进行测评,通过积累一定的评论和销售数据。 测评的益处颇多&#xff0…

【数据结构与算法】8.二叉树的基本概念|前序遍历|中序遍历|后序遍历

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更…

4.3网安学习第四阶段第三周回顾(个人学习记录使用)

本周重点 ①Java入门基础 ②Java方法入门 ③Java面向对象(**重点) ④Java的Maven构建项目工具 ⑤Java其他操作补充 ⑥Java序列化和反序列化 ⑦Url 的DNS 审计链(**难点) ⑧Springboot和前端数据分离(主流使用) ⑨Common Collections(CC链漏洞) 本周主要内容 ①Java入…

使用 Flutter 打造引人入胜的休闲游戏体验

作者 / Zoey Fan 去年,Flutter 休闲游戏工具包进行了一次重大更新。近期在旧金山举办的游戏开发者大会 (GDC) 上,Flutter 首次亮相。GDC 是游戏行业的顶级专业盛会,致力于帮助游戏开发者不断提升开发技能。欢迎您继续阅读,了解开发…

01、创建型-单例模式--只有一个实例

文章目录 前言一、基本介绍1.1 什么是单例模式1.2 为什么要用单例模式1.3 应用场景1.4 单例优缺点 二、单例模式的实现方式2.1 饿汉式单例2.1.1 静态变量方式2.1.2 静态代码块 2.2 懒汉式单例2.2.1 懒汉式单例2.2.2 懒汉式优化①-线程安全2.2.2 懒汉式优化②-双重检查锁2.2.3 懒…

智能人事管理系统:全球团队高效管理之道

在全球化背景下,企业面临着管理分布在各地的员工队伍的挑战。为了确保人力资源管理的高效运作,实现跨地域、跨时区的协同工作,智能化人事管理系统应运而生。本文将重点介绍一款功能全面、智能化的人事管理系统都具备哪些功能,可以…

upload-labs第十七十八关

第十七关 $is_upload false; $msg null;if(isset($_POST[submit])){$ext_arr array(jpg,png,gif);$file_name $_FILES[upload_file][name];$temp_file $_FILES[upload_file][tmp_name];$file_ext substr($file_name,strrpos($file_name,".")1);$upload_file …

【面试必会】线程池创建方式详解

最近面试问道了线程池的创建方式,这里出一篇文章记录下这一知识点! 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的ThreadFactory创建…

【QT】Ubuntu22.04 配置 QT6.5 LTS

【QT】Ubuntu22.04 配置 QT6.5 LTS 文章目录 【QT】Ubuntu22.04 配置 QT6.5 LTS1.注册QT Group的账号2.安装QT Creator3.启动QT Creator报错from 6.5.0, xcb-cursor0 or libxcb-cursor0 is needed to load the Qt xcb platform plugin.4.运行QT的demoReference 1.注册QT Group的…