Linux 进程状态、僵尸进程与孤儿进程

目录

0.前言

1. 进程状态

1.1 定义

1.2 常见进程

2.僵尸进程

2.1 定义

2.2 示例

2.3 僵尸进程的危害与防止方法

3. 孤儿进程

3.1 介绍

3.2 示例

4.小结


(图像由AI生成) 

0.前言

在上一篇文章中,我们介绍了进程的基本概念、进程控制块(PCB)以及如何查看 Linux 系统中的进程状态。这一篇,我们将继续深入探讨进程的各种状态,尤其是僵尸进程和孤儿进程等特殊情况,这些知识对于理解 Linux 系统中的进程管理和资源分配至关重要。

1. 进程状态

1.1 定义

在 Linux 中,进程的状态是进程当前所处的活动阶段或状态的指示。这一状态的定义在 Linux 内核源码中用 task_struct 结构体中的 state 字段表示。这个字段是一个位图,表示进程在何种情况下进行等待或执行操作。内核中的进程状态通过常量数组 task_state_array[] 定义,如下所示:

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

通过这个数组,Linux 内核能够为不同状态的进程进行标识,每个状态都有不同的含义:

  • R (running):表示进程正在运行或准备运行。这是一个活动状态,进程在 CPU 上获得执行时间或正在等待被调度。

  • S (sleeping):表示进程正在睡眠,通常是因为它在等待某个事件发生,比如等待输入/输出(I/O)操作的完成。当条件满足时,进程会被唤醒并恢复运行。

  • D (disk sleep):表示进程处于不可中断的睡眠状态,通常是在等待硬件资源(如磁盘 I/O)的响应。这种状态下的进程不会响应任何信号,除非硬件操作完成。

  • T (stopped):表示进程已被暂停,通常是由用户通过发送 SIGSTOPSIGTSTP 信号来停止进程的执行。进程在这种状态下不会继续执行任何操作,直到接收到继续信号(如 SIGCONT)。

  • t (tracing stop):表示进程被调试器跟踪并暂停执行。调试器可以通过此状态检查进程的运行情况,并可以继续、停止或修改进程的执行。

  • X (dead):表示进程已终止并且即将从系统中清除,通常意味着进程已经彻底退出,内存和资源已释放。

  • Z (zombie):表示僵尸进程,即进程已经结束执行,但其父进程还没有通过 wait() 系统调用获取其退出状态。僵尸进程只保留进程控制块(PCB),不再消耗其他系统资源。

1.2 常见进程

在日常使用 Linux 系统时,上述这些状态中的几种是比较常见的。让我们详细介绍其中几种常见的进程状态:

  1. 运行(R (running)
    这是最活跃的状态,进程处于运行中,意味着该进程正在使用 CPU 资源。即使进程等待 CPU 调度,只要它准备好执行,仍会被标记为 R 状态。这也是大多数活跃进程的正常状态。

  2. 可中断睡眠(S (sleeping)
    这是最常见的等待状态,表示进程正在等待某些条件(如 I/O 完成)。当等待条件满足后,进程将自动被唤醒,恢复执行。使用 pstop 命令时,许多系统后台进程经常处于这种状态。

  3. 不可中断睡眠(D (disk sleep)
    进程处于深度睡眠中,通常在等待某些阻塞的硬件操作(例如磁盘 I/O)。这种状态下的进程无法被信号唤醒,必须等到请求的操作完成。此状态比较罕见,出现时通常与系统 I/O 瓶颈或硬件问题相关。

  4. 停止(T (stopped)
    停止状态的进程通常是被用户手动暂停的。通过 Ctrl+Zkill -STOP 可以将进程送入此状态,典型应用场景是在调试时或暂时停止某些前台任务。

  5. 僵尸(Z (zombie)
    僵尸进程虽然很少见,但却是系统管理中需要注意的一种状态。它们不会消耗系统资源,但过多的僵尸进程可能导致进程号耗尽,系统无法再创建新的进程。

2.僵尸进程

2.1 定义

僵尸进程(Zombie Process)是指一个进程已经完成了它的执行(通过调用 exit() 退出),但它的父进程还没有调用 wait() 系统调用获取它的退出状态。此时,子进程的进程控制块(PCB)依然保存在内存中,等待父进程来回收它的退出信息。在 Linux 中,每个进程都需要一个进程号(PID),如果僵尸进程不被处理,系统将保留它们的 PID,导致可用的 PID 资源被耗尽,最终可能影响系统的正常运行。

僵尸进程本身并不会占用过多的系统资源,但如果产生大量僵尸进程,可能会导致系统进程号耗尽,影响新进程的创建。一般情况下,僵尸进程应该尽快通过父进程调用 wait() 系列函数来处理和回收。

2.2 示例

下面我们通过一个简单的 C 语言代码示例来演示如何创建一个僵尸进程。此代码会创建一个子进程,子进程立即退出,但父进程不调用 wait(),从而让子进程进入僵尸状态。

C语言创建僵尸进程的例子

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>int main() {pid_t pid = fork();if (pid > 0) {// 父进程睡眠一段时间,以便子进程进入僵尸状态sleep(30); // 这里父进程故意不调用 wait(),让子进程变成僵尸} else if (pid == 0) {// 子进程立即退出printf("子进程 (PID: %d) 已经退出,但父进程未调用 wait(),它将成为僵尸进程。\n", getpid());exit(0);} else {// fork 失败perror("fork");exit(1);}return 0;
}

在这个示例中,父进程 fork() 出一个子进程,然后父进程进入睡眠状态,而子进程立即 exit() 退出。由于父进程没有调用 wait(),子进程的状态将变为僵尸状态,直到父进程被唤醒并调用 wait() 函数处理它。

我们可以通过 Linux 中的命令行脚本实时查看该进程的状态。以下是一个简单的命令行脚本,它会每秒钟打印一次所有进程的状态,以便实时监控僵尸进程:

实时监控进程状态的脚本

#!/bin/bash# 使用 ps 命令每秒钟查看进程的状态
while true; doclearps -eo pid,ppid,stat,cmd | grep '[Zz]'sleep 1
done

这个脚本使用 ps -eo pid,ppid,stat,cmd 命令来打印出所有进程的进程号、父进程号、状态和命令。grep '[Zz]' 会过滤出所有处于僵尸状态的进程。脚本会每秒执行一次,显示系统中当前的僵尸进程。运行这个脚本时,用户可以观察到子进程在退出后变成僵尸进程,并在父进程睡眠期间保持僵尸状态。

2.3 僵尸进程的危害与防止方法

僵尸进程的主要危害并不在于它们占用了大量的系统资源,而是:

  1. 占用进程号:每个进程在系统中都有一个唯一的进程号(PID)。系统中的 PID 数量是有限的,过多的僵尸进程会消耗这些可用的进程号,导致系统在需要创建新进程时无法分配新的 PID。如果系统中存在大量僵尸进程,将导致系统无法创建新的进程,从而影响系统的正常运行。

  2. 系统管理复杂化:僵尸进程虽然不占用 CPU 和内存,但它们会增加系统中进程的数量,给系统管理员带来困扰。在 pstop 这样的命令中,这些僵尸进程会持续存在,使得进程管理和问题排查变得更加复杂。

  3. 资源泄露风险:虽然僵尸进程只保留了少量信息,但如果父进程长期不处理这些僵尸进程,相关资源无法完全释放,尤其在一些复杂的进程间通信或多进程的应用中,可能导致资源泄露或系统资源耗尽。

如何防止僵尸进程

  • 父进程主动调用 wait()waitpid():父进程应当及时调用这些函数来处理子进程的退出状态,避免子进程变为僵尸状态。
  • 使用信号处理机制:父进程可以设置 SIGCHLD 信号处理程序,当子进程结束时自动调用 wait() 来清理僵尸进程。
  • init 进程接管:当父进程终止时,孤儿进程会自动被 init 进程接管,init 进程会负责处理这些子进程,避免僵尸状态的出现。

3. 孤儿进程

3.1 介绍

孤儿进程(Orphan Process)是指其父进程已经终止,但子进程仍在继续运行的进程。当父进程退出后,系统自动将这些孤儿进程的父进程重定向为 init 进程(在大多数 Linux 系统中,PID 为 1),由 init 进程负责管理它们。因此,孤儿进程并不会对系统造成问题,init 进程会在这些孤儿进程终止时回收它们的资源。

孤儿进程本身并不是错误或需要纠正的状态,更多情况下,它是一种自然现象。例如,当某个后台服务的父进程意外终止时,子进程继续执行,成为孤儿进程并由 init 进程接管。这种机制确保了系统的稳定性,防止了因为父进程退出而造成的子进程资源泄漏。

3.2 示例

为了更好地理解孤儿进程的工作方式,我们通过一个 C 语言示例代码来演示孤儿进程的生成和处理过程。在此示例中,父进程创建一个子进程,父进程立即终止,而子进程继续运行并成为孤儿进程。

C语言创建孤儿进程的例子

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main() {pid_t pid = fork();if (pid > 0) {// 父进程printf("父进程 (PID: %d) 正在退出...\n", getpid());exit(0);  // 父进程退出,子进程将成为孤儿进程} else if (pid == 0) {// 子进程printf("子进程 (PID: %d, PPID: %d) 开始运行\n", getpid(), getppid());sleep(5);  // 子进程等待几秒,观察它成为孤儿进程的状态printf("子进程 (PID: %d, PPID: %d) 仍然在运行,并已成为孤儿进程\n", getpid(), getppid());exit(0);} else {// fork 失败perror("fork");exit(1);}return 0;
}

解释

  1. 父进程通过调用 fork() 创建了一个子进程。
  2. 父进程立即调用 exit() 终止自身,使得子进程成为孤儿进程。
  3. 子进程在父进程退出后继续执行,并等待 5 秒,确保自己成为孤儿进程。
  4. 子进程打印出自己在成为孤儿进程后的状态,父进程的 PID 变为 1,表示 init 进程已经接管了它。

从输出中可以看到,子进程在父进程退出后继续运行,且子进程的父进程 ID (PPID) 变为 1,说明它已经被 init 进程接管。这就是孤儿进程的典型处理过程。

孤儿进程通常不会给系统带来危害,因为 init 进程会自动管理它们。

4.小结

本篇文章我们深入探讨了 Linux 系统中的进程状态,了解了系统如何管理进程的不同阶段。尤其是僵尸进程和孤儿进程这两种特殊进程状态,在日常的系统管理和故障排查中经常遇到。理解这些概念不仅有助于我们优化系统资源的使用,还能够在需要时快速定位和处理系统中潜在的问题。对于僵尸进程,关键在于父进程的正确处理;对于孤儿进程,系统的 init 进程会自动接管,用户通常不需要过多干预。

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

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

相关文章

C语言自定义类型联合和枚举(25)

文章目录 前言一、联合体联合体的声明联合体的特点联合体和结构体内存布局对比联合体的大小计算联合体的实际使用样例礼品兑换单判断当前机器是大端还是小端 二、枚举枚举的定义枚举类型的声明枚举类型的优点枚举类型的使用 总结 前言 关于自定义类型除了我们常用的结构体&…

Python机器视觉:01- 利用列表和切片操作 - 做一个弧线和图片相交的mask区域

前言&#xff1a; Python的列表处理&#xff0c;在机器视觉中经常被用到&#xff0c;这里结合基本的概念机器视觉实践案例&#xff0c;成文如下&#xff1a; 本身将实现一个&#xff0c;弧线的mask填充&#xff1a;这个mask是我的一个天文项目的应用&#xff0c;目的在于将月…

实现Xshell与虚拟机中Linux服务器的连接(附常见错误解决)

前言 Xshell是一个强大的安全终端模拟软件&#xff0c;它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET 协议。Xshell 通过互联网到远程主机的安全连接以及它创新性的设计和特色帮助用户在复杂的网络环境中享受他们的工作。 本文将介绍Xshell与虚拟机中Linux服务器连接…

Web APIs——Dom获取属性操作

1.变量声明 1.1以后声明变量我们优先使用哪个&#xff1f; const 有了变量先给const&#xff0c;如果发现它后面是要被修改的&#xff0c;再改为let 1.2 为什么const声明的对象可以修改里面的属性&#xff1f; 因为对象是引用类型&#xff0c;里面存储的是地址&#x…

自动驾驶核心技术:感知融合、规划决策、控制执行

1、前言 简单来说&#xff0c;实现自动驾驶需要解决三个核心问题&#xff1a;“我在哪?我要去哪?我该如何去?”能完整解决这三个问题就是真正的自动驾驶。 目前&#xff0c;自动驾驶汽车关键技术主要包括环境感知、精准定位、决策与规划、控制与执行、高精地图与车联网V2X以…

大学生就业招聘:Spring Boot系统的设计与实践

5系统详细实现 5.1 用户模块的实现 5.1.1 求职信息管理 大学生就业招聘系统的用户可以管理自己的求职信息&#xff0c;可以对自己的求职信息添加修改删除操作。具体界面的展示如图5.1所示。 图5.1 求职信息管理界面 5.1.2 首页 用户登录可以在首页看到招聘信息展示也一些求职…

Flet介绍:平替PyQt的好用跨平台Python UI框架

随着Python在各个领域的广泛应用&#xff0c;特别是在数据科学和Web开发领域&#xff0c;对于一个简单易用且功能强大的用户界面&#xff08;UI&#xff09;开发工具的需求日益增长。传统的Python GUI库如Tkinter、PyQt虽然功能强大&#xff0c;但在易用性和现代感方面略显不足…

算法篇1:双指针思想的运用(1)--C++

一.算法解析 双指针&#xff0c;顾名思义就是两个指针&#xff0c;常见的算法中&#xff0c;我们可以看到两种&#xff1a; 1.对撞指针&#xff1a;一般用于顺序结构&#xff0c;也称为左右指针。 对撞指针从两端向中间移动。一个指针从最左端开始&#xff0c;另一个从最右端…

比较搜索难度曲线5s1-4和4s1

在行列可自由变换的条件下&#xff0c;平面上的5点结构只有34个,4点结构有16个 (A,B)---6*n*2---(0,1)(1,0) 让B全是0。当收敛误差为7e-4&#xff0c;收敛199次取迭代次数平均值。让隐藏层节点数n分别为10&#xff0c;15&#xff0c;20&#xff0c;25&#xff0c;30&#xff…

C(十四)while、for、do-while循环综合(一)

uu们&#xff0c;小弟我本科在读&#xff0c;文章我会一直坚持更新下去&#xff0c;包括但不限于C初阶、C进阶、数据结构、C、Linux、MySQL、项目、QT开发、各种算法&#xff08;之后会持续更新&#xff09;&#xff0c;并且站在小白的视角尽可能通俗易懂地把这些写出来&#x…

【Android】获取备案所需的公钥以及签名MD5值

目录 重要前提 获取签名MD5值 获取公钥 重要前提 生成jks文件以及gradle配置应用该文件。具体步骤请参考我这篇文章&#xff1a;【Android】配置Gradle打包apk的环境_generate signed bundle or apk-CSDN博客 你只需要从头看到该文章的配置build.gradle&#xff08;app&…

25重庆长安深蓝控制器开发面试经验 深蓝最常见面试问题总结

【面试经历】 秋招气氛组选手的第一场面试,9.17网申,9.24电话约面,9.26线上面试。问得很细,全长约1个小时 1. 自我介绍、项目介绍 2.项目细节,遇到了哪些困难;有没有PCB设计经验DC-DC芯片选型,电源噪声的原因、怎么消除、 3.画BUCK和BOOST拓扑图,讲原理 4.了解MCU的主…

西电25考研 VS 24考研专业课大纲变动汇总

01专业课变动 西安电子科技大学专业课学长看到953网络安全基础综合变为 893网络安全基础综合&#xff0c;这是因为工科要求都必须是8开头的专业课&#xff0c;里面参考课本还是没变的&#xff0c;无非就是变了一个名字 对于其他变动专业课也是同理的 02专业课考纲内容变化 对于…

uniapp中检测应用更新的两种方式-升级中心之uni-upgrade-center-app

uniapp一个很是用的功能&#xff0c;就是在我们发布新版本的app后&#xff0c;需要提示用户进行app更新&#xff0c;并告知用户我们新版的app更新信息&#xff0c;以使得用户能及时使用上我们新开发的功能&#xff0c;提升用户的实用度和粘性。注意:这个功能只能在app端使用 效…

创建django项目时,不同的编译类型有什么区别

这里主要提及的是 project venv 和 Custom environment 两种类型。 简单来说&#xff0c;project venv 是Python 3.3及以上版本中自带的虚拟环境管理工具&#xff0c;使用venv可以为每个项目创建一个独立的环境&#xff1a;python -m venv myprojectenv &#xff08;项目名后e…

【3D目标检测】激光雷达和相机联合标定(一)——ROS同步解包

ROS同步解包 引言1 鱼香ROS一键安装ros-docker脚本&#xff1a;2 指定目录映射3 数据解包3.1 解包脚本3.2 依赖安装3.3 运行脚本&#xff0c;解包 引言 总结步骤如下&#xff1a; 采集同步数据&#xff1a;ROS录制&#xff08;推荐&#xff09;&#xff0c;或者代码同步触发采…

如何使用工具删除 iPhone 上的图片背景

在 iPhone 上删除背景图像变得简单易行。感谢最近 iOS 更新中引入的新功能。如今&#xff0c;iOS 用户现在可以毫不费力地删除背景&#xff0c;而无需复杂的应用程序。在这篇文章中&#xff0c;您将学习如何使用各种方法去除 iPhone 上的背景。这可确保您可以选择最适合您偏好的…

通信工程学习:什么是IP网际协议

IP&#xff1a;网际协议 IP网际协议&#xff08;Internet Protocol&#xff0c;简称IP&#xff09;是整个TCP/IP协议栈中的核心协议之一&#xff0c;它负责在网络中传送数据包&#xff0c;并提供寻址和路由功能。以下是对IP网际协议的详细解释&#xff1a; 一、对IP网际协议的…

哈尔滨自闭症学校寄宿条件与优势解析

自闭症儿童的希望之光&#xff1a;广州星贝育园寄宿制学校深度解析 在当今社会&#xff0c;自闭症儿童作为一群需要特别关注和照顾的群体&#xff0c;其教育与康复问题日益受到社会各界的重视。自闭症儿童不仅需要专业的康复训练&#xff0c;还需要一个稳定、温馨且充满爱的环…

Java:插入排序

目录 排序的概念 插入排序 直接插入排序 哈希排序 排序的概念 排序&#xff1a;所谓的排序&#xff0c;就是使一串记录&#xff0c;按照某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个…