【Linux】——进程状态僵尸进程孤儿进程

目录

前言

基本进程状态

运行状态

阻塞状态

挂起状态

Linux下的进程状态

僵尸进程

孤儿进程 

结语


前言

  进程的状态反映了它在执行过程中的不同阶段,例如创建、就绪、运行、阻塞和终止等。这些状态之间的转换由操作系统的调度算法和进程的行为共同决定。通过了解进程状态的变化,我们不仅可以更好地理解程序的执行流程,还能在开发过程中更高效地调试和优化代码。

  在本篇博客中,我们将深入探讨进程的几种主要状态,分析它们之间的转换关系,并结合实际应用场景,帮助读者掌握进程状态管理的核心概念。无论你是操作系统初学者,还是希望进一步巩固相关知识的开发者,相信本文都能为你提供有价值的参考。接下来,让我们从进程的基本状态开始,逐步揭开进程管理的奥秘。


1.基本进程状态

我们在《看完这一篇,99%的人都懂进程》一文中,以及认识到,在内存中的进程是动态的,是会变化的

这里指的变化,就是进程状态的变化

操作系统下的进程,有三个基本状态

  1. 运行状态
  2. 阻塞状态
  3. 挂起状态

接下来,我们将一一对这些进程基本状态进行讲解

1.1运行状态

当进程被CPU调度,或者处于CPU的调度队列当中的时候,就代表此时进程处于运行状态

现代计算机或有单核、双核、甚至多核

拿单核来说,我们说过操作系统管理硬件和软件,其中管理的硬件也包括CPU

在内存空间中,操作系统会为CPU维护一个运行队列

当一些进程准备好,可以运行,操作系统就会将这些进程放入CPU的运行队列当中,再根据调度算法让CPU调度其中的进程

操作系统如何得知该进程准备好了呢?

通过进程PCB上的状态属性(status),当 状态属性= 运行,操作系统就会将这个进程放入CPU的运行队列当中

而PCB上的状态属性,又是谁设置的呢?

也是操作系统!操作系统会对进程进行判断,根据进程目前的情况、与其关联的硬件情况,对进程额状态判定,设置进程PCB的状态属性

1.2阻塞状态

当进程不动了,运行不下去,无法执行接下来的代码,我们就任务该进程处于阻塞状态

当进程处于运行状态,会进入运行队列

那么进程处于阻塞状态,也会进行阻塞队列

我们的进程多多少少会与硬件进行交互,获取硬件数据或者发送给硬件数据

但是如果硬件此时没有数据给进程或者没有能力接收进程的数据,即硬件资源没有准备好,此时的进程就会卡住,无法进行下一步,从而阻塞,当相关资源准备好了,进程就会重新进入运行状态,开始执行下一步代码。

如何知道硬件资源准备好,又如何知道硬件资源没有准备好呢?

操作系统是管理软件和硬件的好手,它管理诸多的硬件

操作系统在内存空间中会为每个硬件创建相应的结构体对象,并用数据结构将这些结构体对象联系起来,进行统一管理(先描述,再组织)

操作系统对硬件结构体对象管理,就是对硬件本身进行管理,也能从硬件结构体对象的属性上,获得硬件的信息,如资源是否准备好等等。

1.3挂起状态

当一个阻塞进程被操作系统操作,其在内存空间的代码和数据被操作系统置换到磁盘,而进入不能运行的状态,我们将这种状态称为挂起状态

为什么被挂起?

  1. 用户主动挂起
  2. 操作系统迫于特殊情况进行挂起

我们讨论一下第二种情况

当内存接近圆满,整个计算机的运行会收到影响,甚至宕机

为了让计算机能够正常运行,操作系统就会找到处于阻塞状态的进程

这些处于阻塞状态的进程,不仅不执行任务,还占据内存空间,没用还消耗资源

操作系统就会将这些暂时不工作的进程的代码和数据调换到磁盘之上,待到内存空间富足,再将这些代码和数据重新加载到内存中

内存与外设的交互,会大大增加时间损耗,这属于操作系统为了让计算机存活的无奈之举。

磁盘中保存从内存而来的数据与代码的区域,叫作  swap区

swap区的大小是用户可以主动设置的,建议为内存的一倍,不建议将该区域设置过大,过大会导致操作系统依赖,不断将代码和数据写入该区域,从而导致频繁地内存和外设交互,大大降低效率

2.Linux下的进程状态

我们上面介绍的进程状态,是操作系统中的基本进程状态

每个操作系统中都会有,但不一定和上面的基本状态名字相同,即同内不同外

以下是Linux中的具体进程状态

其中,R运行状态就是我们上面的运行状态,睡眠状态就是阻塞状态

来浅浅看一段有意思的代码

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

朴素无华,运行一下,并使用 ps ajx 进行查看

 

可以发现,该进程处于睡眠状态,这是为什么呢?

代码中的打印语句,printf是向显示器中打印,而显示器资源也是需要准备的,当显示器资源没有准备好的时候,该进程就会进入阻塞队列,因为频繁的打印,导致该进程不断进入阻塞队列,又不断唤醒运行,但Linux操作系统为了方便,就会将该进程置为睡眠状态,偶尔有运行状态

其中,进程的状态的都是由操作系统决定的,操作系统再根据这个状态对进程安排

2.1深度睡眠状态(disk sleep)

上面介绍的睡眠状态属于浅度睡眠,浅度睡眠的进程是可以被操作系统终止的

只要用户向操作系统发出终止进程的请求,浅度睡眠的进程就会被终止

而深度睡眠的进程,不会被操作系统强行终止

为什么会有深度睡眠呢?

进程访问资源而得不到资源的时候,就会陷入睡眠

如果此时的进程,是在对磁盘写入数据,将数据交给磁盘写入的时候,进程也会进入等待队列,等待写入数据完成 

这时候,如果终止该进程,我们将无法得知数据写入磁盘是否完成,如果严重甚至会导致数据在磁盘的位置丢失。

如果数据十分重要,丢失的话将造成无法挽回的损失,为了照顾这种向磁盘写入数据的进程,操作系统就会将其设置为深度睡眠状态,无论发生什么,都不会强行终止这个进程!

2.2暂停状态(T)

在Linux命令行中,可以发送暂停信号给目标进程,让其进入等待队列,这种进程状态成为暂停状态

2.3追踪暂停状态(T)

进程的暂停状态是可以控制的,如使用debug进程调试另一进程,另一进程所处于的状态就是最终暂停状态

2.4死亡状态(X)

当进程完成任务,代码和数据,以及PCB全部在内存空间中被销毁时,进程状态就是死亡状态

3.僵尸进程

在《轻松搞定进程fork》一文中,我们提过,我们创建进程是为了让新的进程替我们完成其他任务

新进程去执行任务就够了吗?

我们也需要知道任务完成得如何

如何知道呢?

进程完成相应任务就会退出,它的退出信息就需要被我们获取,有了这个退出信息,我们就知道进程任务完成得如何

这个退出信息在哪里?

一切都在进程的PCB当中!

所以,当一个进程退出的时候,我们不会让其立刻退出,我们得知道这个进程的任务完成情况,进程退出有两个阶段

  1. 进程退出,代码和数据在内存中被销毁,退出信息被操作系统写入进程的PCB当中
  2. 进程的PCB被读取,PCB在内存空间中被销毁

我们将进程退出时,代码和数据被销毁,但PCB仍然存在,退出信息没有被获取时的状态称为僵尸状态!处于僵尸状态的进程,即为僵尸进程

回收进程PCB的操作必须是进程的创建者完成的,所以一般回收进程的就是创建该进程的父进程或者操作系统

这也就是为什么所有的子进程必须有父进程的原因

如果子进程的PCB的退出信息,一直没有被父进程或者操作系统获取,该进程就会一直是僵尸状态,其PCB就会一直存在于内存空间,造成内存泄露

如果子进程的PCB一直没有被父进程或者操作系统获取,该进程PCB就需要被操作系统管理维护,一定程度增加操作系统不必要的工作量

因此,获取僵尸进程的PCB刻不容缓,我们可以使用 wait函数 和 waitpid函数,来回收子进程

3.1wait函数

wait() 函数会阻塞调用进程,直到任意一个子进程终止。它返回终止子进程的进程 ID(PID),并将子进程的退出状态存储在 status 参数中,包含于sys/types.h 和 sys/wait.h 头文件中

函数造型

pid_t wait(int *status);

参数说明

  • status:指向一个整数的指针,用于存储子进程的退出状态。可以使用宏(如 WIFEXITEDWEXITSTATUS 等)来解析状态。

返回值

  • 成功时返回终止子进程的 PID。
  • 失败时返回 -1(例如没有子进程)

基本用法

int status;
pid_t child_pid = wait(&status);

注意:wait是等待当前父进程的所有子进程,等待成功一个就直接返回结果 

3.2waitpid函数

waitpid函数 比 wait函数 更灵活,可以指定要等待的子进程 PID,并提供非阻塞选项。

函数造型

#include <sys/types.h>
#include <sys/wait.h>pid_t waitpid(pid_t pid, int *status, int options);

参数说明

  • pid:指定子进程的pid
  • status:同 wait(),用于存储子进程的退出状态。
  • options:控制函数行为的选项,WNOHANG为非阻塞等待,没有结果立刻返回0,WUNTRACED会等待子进程停止或终止。

返回值说明

  • 成功时返回终止子进程的 PID。
  • 如果指定了 WNOHANG 且没有子进程终止,返回 0。
  • 失败时返回 -1

基本用法

int status;
pid_t child_pid = waitpid(pid, &status, 0);

4.孤儿进程 

子进程一定是父进程创建的,当父进程比子进程先退出的时候,子进程就相当于没有了父进程,我们将这种没有父进程的进程,称为孤儿进程

没有父进程,就没有办法回收孤儿进程的退出信息

为了避免孤儿进程的退出信息没有父进程回收,操作系统会为其分配一个父进程,让这个父进程完成对子进程的退出信息获取,这个新分配的父进程一般是操作系统本身,所以我们才会说,子进程的PCB中的退出信息,一般由父进程或者子进程获取。

验证一下:新分配的父进程是操作系统本身

pid_t pid = fork();if (pid == 0) {// 子进程printf("Child process is running, PID: %d\n", getpid());sleep(10); // 等待父进程终止printf("Child process is still running, now parent PID: %d\n", getppid());} else if (pid > 0) {// 父进程printf("Parent process is running, PID: %d\n", getpid());sleep(2); // 父进程提前终止printf("Parent process is done\n");} else {perror("fork failed");return 1;}return 0;

在这段代码下,父进程会比子进程先退出,子进程会重新被操作系统分配父进程

运行一下

这个pid为1的进程,就是最先启动的进程——操作系统! 


结语

  通过本次关于进程状态的讲解,我们从进程的基本状态出发,深入探讨了进程的生命周期及其状态转换机制。无论是进程的创建、就绪、运行、阻塞还是终止,每一种状态都反映了操作系统对资源管理和任务调度的精妙设计。

  希望本次讲解能为你提供清晰的知识框架,并激发你对操作系统更深层次的探索兴趣。如果你有任何疑问或想进一步讨论相关话题,欢迎随时交流。感谢你的阅读,期待在未来的学习中与你再次相遇!

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

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

相关文章

信创系统极速文件查找:locate 命令详解

原文链接&#xff1a;信创系统极速文件查找&#xff1a;locate 命令详解 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇信创终端操作系统上 locate 命令详解的文章。在 Linux 及信创终端操作系统&#xff08;如 统信 UOS、麒麟 KOS&#xff09;中&#xff0c;查找…

鸿蒙数据持久化之首选项

场景介绍 用户首选项为应用提供Key-Value键值型的数据处理能力&#xff0c;支持应用持久化轻量级数据&#xff0c;并对其修改和查询。当用户希望有一个全局唯一存储的地方&#xff0c;可以采用用户首选项来进行存储。Preferences会将该数据缓存在内存中&#xff0c;当用户读取…

PyTorch分布式训练中各节点如何通信

深度学习 文章目录 深度学习前言pytorch如何初始化分布式训练怎么知道要使用哪几台机器进行训练的如何根据标识进行初始化&#xff08;init_method&#xff09;如何获取进程的唯一标识rank如何实现数据如何分发 前言 同学们在处理分布式训练时经常会遇到以下几个疑问&#xff…

[数据结构]排序之 归并排序(有详细的递归图解)

一、非递归 基本思想&#xff1a; 归并排序&#xff08; MERGE-SORT &#xff09;是建立在归并操作上的一种有效的排序算法 , 该算法是采用分治法&#xff08; Divide andConquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#x…

在本地跑通spark环境

官网下载spark 下载spark 解压就好 本地配置环境变量 配置环境变量&#xff08;系统环境变量&#xff09; 新增 SPARK_HOME 变量名&#xff1a;SPARK_HOME 变量值&#xff1a;F:\class\spark\Spark_env\spark-3.4.4-bin-hadoop3 配置 PATH&#xff0c;新增如下&#xff1a…

UE5材质法线强度控制节点FlattenNormal

连法 FlattenNormal内部是这样的 FlattenNormal的作用是用来调整法线强度 连上FlattenNormal后 拉高数值

Appium使用文档

Appium旨在支持许多不同平台&#xff08;移动端、网页端、桌面端等&#xff09;的UI自动化。不仅如此&#xff0c;它还旨在支持用不同语言&#xff08;JS、Java、Python等&#xff09;编写的自动化代码。 1. 环境搭建 资源下载&#xff1a; 链接: https://pan.baidu.com/s/1K5Q…

Python绘图技巧,主流绘图库

一、主流绘图库概览 1. 核心工具对比 库名称特点适用场景Matplotlib基础绘图库&#xff0c;高度可定制科学绘图、论文图表Seaborn基于Matplotlib&#xff0c;统计图表优化数据分布、关系可视化Plotly交互式可视化&#xff0c;支持网页输出仪表盘、动态数据展示Pandas内置简易…

使用LLM自动化生成微电网Simulink模型

&#x1f680; 使用LLM自动化生成微电网Simulink模型&#xff01;⚡ 在构建微电网仿真模型时&#xff0c;我们通常需要手动拖拽模块、设置参数&#xff0c;耗费大量时间。现在&#xff0c;通过结合LLM&#xff08;如 GPT-4&#xff09;与 MATLAB 脚本&#xff0c;我们可以自动…

Git常用操作之GitLab

Git常用操作之GitLab 小薛博客官网&#xff1a;小薛博客Git常用操作之GitLab官方地址 1、GitLab安装 https://gitlab.cn/install/ 1、Docker安装GitLab https://docs.gitlab.cn/jh/install/docker.html 1、设置卷位置 在设置其他所有内容之前&#xff0c;请配置一个新的…

【AI】AI编程助手:Cursor、Codeium、GitHub Copilot、Roo Cline、Tabnine

文章目录 一、基本特性对比二、收费标准三、私有部署能力1、Tabnine2、Roo Code 三、代码补全与自然语言生成代码四、安装独立的IDE安装插件安装 五、基本使用&#xff08;一&#xff09;Cursor&#xff08;二&#xff09;GitHub Copilot1、获取代码建议2.聊天1&#xff09;上下…

[贪心算法]买卖股票的最佳时机 买卖股票的最佳时机Ⅱ K次取反后最大化的数组和 按身高排序 优势洗牌(田忌赛马)

1.买卖股票的最佳时机 暴力解法就是两层循环&#xff0c;找出两个差值最大的即可。 优化&#xff1a;在找最小的时候不用每次都循环一遍&#xff0c;只要在i向后走的时候&#xff0c;每次记录一下最小的值即可 class Solution { public:int maxProfit(vector<int>& p…

康谋方案 | AVM合成数据仿真验证方案

随着自动驾驶技术的快速发展&#xff0c;仿真软件在开发过程中扮演着越来越重要的角色。仿真传感器与环境不仅能够加速算法验证&#xff0c;还能在安全可控的条件下进行复杂场景的重复测试。 本文将分享如何利用自动驾驶仿真软件配置仿真传感器与搭建仿真环境&#xff0c;并对…

Django Rest Framework 创建纯净版Django项目部署DRF

描述创建纯净版的Django项目和 Django Rest Framework 环境的部署 一、创建Django项目 1. 环境说明 操作系统 Windows11python版本 3.9.13Django版本 V4.2.202. 操作步骤(在Pycharm中操作) 创建Python项目drfStudy、虚拟环境 ​虚拟环境中安装 jdangopip install django==4.…

数据结构篇——二叉树的存储与遍历

一、引入 书接上文&#xff0c;文于此续。上文我们学到了树的存储结构&#xff0c;那么今天&#xff0c;我们来学习下几种特殊的二叉树以及关于它的各种遍历&#xff0c;让我们一起加油吧。 二、特殊的二叉树 二叉树的特殊形式这里介绍3种&#xff0c;其中需要着重记忆的有…

Vulnhub-wordpress通关攻略

姿势一、后台修改模板拿WebShell 第一步&#xff1a;进⼊Vulhub靶场并执⾏以下命令开启靶场&#xff1b;在浏览器中访问并安装好.... 第二步&#xff1a;找到外观--编辑--404.php&#xff0c;将原内容删除并修改为一句话木马&#xff0c;点击更新--File edited successfully. &…

「清华大学、北京大学」DeepSeek 课件PPT专栏

你要的 这里都打包好啦&#xff0c;快快收藏起来&#xff01; 名称 链接 团队简介 类型 DeepSeek——从入门到精通 1️⃣ DeepSeek从入门到精通「清华团队」 清华大学新闻与传播学院 新媒体研究中心 元宇宙文化实验室 PPT课件 DeepSeek如何赋能职场应用? ——从提示语…

【docker】--- 详解 WSL2 中的 Ubuntu 和 Docker Desktop 的区别和关系!

在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。【WSL 】--- Windows11 迁移 WSL 超详细指南 —— 给室友换一个宿舍! 开发环境一、引…

【图像处理基石】什么是HDR图片?

1. 什么是HDR图片&#xff1f; HDR&#xff08;高动态范围图像&#xff0c;High Dynamic Range&#xff09;是一种通过技术手段扩展照片明暗细节的成像方式。以下是关于HDR的详细说明&#xff1a; 核心原理 动态范围&#xff1a;指图像中最亮和最暗区域之间的亮度差。人眼能…

HarmonyOS Next中的弹出框使用

HarmonyOS Next弹出框概述及分类 弹出框是一种模态窗口&#xff0c;通常用于在保持当前上下文环境的同时&#xff0c;临时展示用户需关注的信息或待处理的操作。用户需在模态弹出框内完成相关交互任务之后&#xff0c;才能退出模态模式。弹出框可以不与任何组件绑定&#xff0…