当前位置: 首页 > news >正文

聊聊僵尸进程

文章目录

  • 1. 前言
    • 1.1 什么是僵尸进程
    • 1.2 为什么需要关注僵尸进程
  • 2. 僵尸进程的产生
    • 2.2 为什么会产生僵尸进程
    • 2.3 举个栗子
  • 3. 僵尸进程的影响
    • 3.1 僵尸进程为何会占用系统资源
    • 3.2 操作系统如何知道哪个资源需要被释放
    • 3.3 什么是进程表
    • 3.4 什么是PCB
  • 5. 如何处理僵尸进程
    • 4.1 识别僵尸进程
      • 第一种方法
      • 第二种方法
    • 4.3 清理僵尸进程
      • 1. 找到僵尸进程的父进程ID(PPID)
      • 2. 向父进程发送`SIGCHLD`信号
  • 6. 实例分析
  • 7. 参考文档

1. 前言

1.1 什么是僵尸进程

僵尸进程,也被称为"defunct process" 我们在看国外的一些博客的时候会发现僵尸进程又称为 Zombie Processes
它是一种已经终止但是仍然在进程表中存在的进程。这种情况通常发生在父进程还没有来得及读取子进程的退出状态,而子进程已经结束,这样子进程虽然已经结束,但是在操作系统中仍然保留了相关记录。
《Processes in a Zombie (Z) or Defunct State》
《How to Clean a Linux Zombie Process》

1.2 为什么需要关注僵尸进程

僵尸进程可能会导致一些问题。首先,它们占用了系统资源。虽然僵尸进程自身已经不再运行,但是它在进程表中的记录仍然会占用系统资源,如果有大量的僵尸进程,可能会消耗掉所有的进程表空间,导致无法创建新的进程。其次,僵尸进程可能会影响到其他进程的运行,特别是那些需要读取进程状态或者和已经终止的进程进行交互的进程。因此,对于僵尸进程,我们需要及时处理,避免它们引起更大的问题。

2. 僵尸进程的产生

2.2 为什么会产生僵尸进程

在操作系统中,僵尸进程是指原本已经结束运行并退出的进程,但是它在系统的进程表中仍然保留有记录。这种情况通常有以下几种可能:

  1. 父进程没有调用wait()或waitpid()来获取子进程的结束状态。当子进程结束运行后,系统会向父进程发送一个SIGCHLD信号。如果父进程没有处理这个信号或者没有正确地获取子进程的结束状态,那么子进程就会变成僵尸进程。

  2. 父进程在子进程结束之前就已经结束了。这种情况下,子进程会被init进程接管,init进程会定期调用wait()来回收这些僵尸进程。

  3. 父进程由于某种原因没有接收到SIGCHLD信号,例如父进程正在执行一个长时间的任务或者被阻塞了。这种情况下,子进程的结束状态就无法被父进程获取,导致子进程成为僵尸进程。

通俗的说,僵尸进程主要是由父进程没有正确处理子进程的结束状态造成的。虽然僵尸进程自身不会消耗除了进程表之外的其他资源,但是如果有大量的僵尸进程存在,那么进程表的空间就会被耗尽,新的进程将无法创建,对系统性能会有影响。

2.3 举个栗子

在这里插入图片描述

举例来说,假设有一个父进程P,它创建了一个子进程C。现在子进程C执行了一些任务后完成了。这时,内核发送一个SIGCHLD信号给父进程P,通知它子进程C已经完成了任务。

如果父进程P在创建子进程C时已经编程执行wait()系统调用,那么父进程P会接收到SIGCHLD信号后,执行wait()系统调用,读取子进程C的状态和退出码,并同时清除子进程C在进程表中的记录。

但是,如果父进程P在创建子进程C时没有编程执行wait()系统调用,那么它就无法读取子进程C的状态和退出码,也无法清除子进程C在进程表中的记录。这就导致子进程C虽然已经完成了任务,但是它的僵尸状态还是留在进程表中,显示为一个僵尸进程。

另外,如果父进程P在接收到SIGCHLD信号时,由于某种原因(比如过载等)无法处理该信号,那么这也会导致子进程C变成一个僵尸进程。

这些僵尸进程会占用系统资源,虽然它们不再执行任何任务,但是它们在进程表中的记录仍然存在。这可能会导致系统资源的浪费,甚至在极端情况下,可能因为进程表已满而无法再创建新的进程。

3. 僵尸进程的影响

3.1 僵尸进程为何会占用系统资源

每个进程结束时,都会产生一个退出状态,这个状态需要被它的父进程来回收。在父进程回收这个状态之前,系统会保留一部分信息(比如进程ID、进程状态和退出码等),这样父进程就可以知道其子进程结束的详细情况。这部分信息是存放在系统内存中的,因此结束的进程直到被其父进程回收之前都会占用一些内存资源。

这就是为何僵尸进程会占用系统资源的底层原理。僵尸进程就是已经结束,但是其父进程还未回收其状态的进程,因此它们还会占用一部分系统资源。

在Linux系统中,如果父进程没有回收子进程的状态,内核会把这个任务交给init进程(进程ID为1的进程)来完成。这就是为什么在系统中看到的大部分僵尸进程其父进程ID都是1的原因。

在多任务环境下,如果僵尸进程过多,理论情况下可能会导致进程表已满,从而无法创建新的进程,影响到其他任务的正常进行。看清楚是理论情况下,其实在进程表沾满之前其他资源肯定已经耗尽了已经不可能分配进程了。此外,僵尸进程还可能导致系统响应时间变慢,因为系统需要花费更多的时间来处理并不需要的进程,这对于需要快速响应的系统来说是非常不利的。同时,僵尸进程占用的内存资源也可能导致其他需要更多内存的任务无法得到足够的内存资源,从而影响其性能。

3.2 操作系统如何知道哪个资源需要被释放

这就不得不说 操作系统两个相关的概念 进程表和PCB
进程表是操作系统中管理进程的数据结构之一。它是一个存储所有进程信息的表格,每个进程在表格中都有一个对应的表项。而操作系统通过进程控制块(Process Control Block, PCB)来记录和管理系统中的各个进程。

每个进程有自己的PCB,它包含了这个进程的所有重要信息,如进程状态、程序计数器、CPU寄存器和堆栈指针、优先级、内存分配状况、资源状态、I/O状态等信息。

当一个进程结束的时候,操作系统会根据该进程的PCB中记录的信息,来知道需要释放哪些资源,例如内存资源、I/O设备等。

操作系统还会通过一些内部的数据结构来记录资源的使用情况,例如内存管理子系统会用位图或者链表来记录内存的分配情况,文件系统会用索引节点(inode)来记录文件的分配情况等。这些都可以帮助操作系统了解哪些资源正在被使用,哪些资源已经空闲,从而在需要的时候正确地释放或者分配资源。

3.3 什么是进程表

进程表是操作系统内核内部的一种数据结构,用于跟踪和管理系统中的所有进程。每当创建一个新的进程时,操作系统就会在进程表中为其分配一个新的条目。
在这里插入图片描述

进程表中的每个条目通常包含以下信息

信息类别详细描述
进程ID(PID)每个进程的唯一标识符
状态进程的当前状态(如运行、就绪、阻塞等)
优先级进程的调度优先级
所有者创建该进程的用户或者进程的用户ID
进程计数器记录了进程下一条要执行的指令的地址
CPU寄存器保存了进程上下文切换时的CPU寄存器状态
内存管理信息记录了进程的内存布局以及进程使用的虚拟内存和物理内存等信息
文件描述符表记录了进程打开的所有文件和网络套接字
执行环境如环境变量等

进程表对于操作系统来说极为重要,是实现多任务和进程隔离等核心功能的关键。进程表的主要作用是帮助操作系统管理和调度进程。具体来说,它有以下几个作用:

  1. 进程调度:操作系统根据进程表中的信息(如进程状态、优先级等)来决定下一个要运行的进程。

  2. 进程管理:操作系统通过进程表来跟踪每一个进程的状态,如运行、就绪、阻塞等。

  3. 上下文切换:当CPU从一个进程切换到另一个进程时,操作系统会保存当前进程的状态到进程表,并从进程表中恢复新的进程的状态。

  4. 内存管理:操作系统根据进程表中的信息来管理进程的内存分配,包括虚拟内存和物理内存。

  5. 文件系统管理:操作系统通过进程表中的文件描述符表来跟踪每个进程所打开的文件和网络套接字。

  6. 资源管理:操作系统使用进程表来管理和跟踪进程所需的其他系统资源,如I/O设备、信号量、消息队列等。

3.4 什么是PCB

PCB,全称为Process Control Block,中文名为进程控制块。它是操作系统中一个非常重要的数据结构,用于保存和描述一个进程的基本信息和运行状态。
通俗的说,PCB就是操作系统对进程的一种抽象,它包含了操作系统管理和控制进程所需要的所有信息。
在这里插入图片描述

PCB的主要作用如下

  1. 进程调度:在多道程序设计中,操作系统需要进行进程的调度和切换,PCB中保存的进程状态和调度信息(例如进程优先级)可以帮助操作系统做出决策。

  2. 进程同步和通信:PCB中保存了进程的同步和通信机制(比如信号量等),帮助实现进程间的协调运行。

  3. 进程管理:通过PCB,操作系统可以对进程进行管理和控制,如创建、终止进程,修改进程的状态等。

  4. 资源管理:PCB中保存了进程的资源使用情况(比如CPU时间、内存空间等),可以帮助操作系统进行资源的分配和回收。

5. 如何处理僵尸进程

4.1 识别僵尸进程

识别僵尸进程的方法是使用ps命令。在查看僵尸进程时,只需要关注STAT列的值是否为Z

第一种方法

  1. 查看所有进程的状态:
$ ps aux

输出示例:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  16444  2580 ?        Ss   Jan21   0:02 /sbin/init
root         2  0.0  0.0      0     0 ?        S    Jan21   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    Jan21   0:01 [ksoftirqd/0]
...
user     32345  0.0  0.1  34364  2928 pts/1    Z    01:30   0:00 [myprocess] <defunct>
...

在上面的输出中,STAT列的值为Z的进程(如PID为32345的进程)就是僵尸进程。

第二种方法

  1. 也可以使用以下命令直接列出所有僵尸进程:
$ ps aux | grep -w Z

输出示例:

user     32345  0.0  0.1  34364  2928 pts/1    Z    01:30   0:00 [myprocess] <defunct>

这条命令会过滤出所有STAT列值为Z的进程。

4.3 清理僵尸进程

要清理僵尸进程,需要向其父进程发送SIGCHLD信号以通知它回收子进程。通常情况下,父进程会在子进程结束时自动回收它。但在某些情况下,父进程可能没有正确地回收子进程,导致子进程成为僵尸进程。下面是清理僵尸进程的方法:

1. 找到僵尸进程的父进程ID(PPID)

$ ps -el | grep -w Z

输出

F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 Z  1000 32345  1001  0  80   0 -     0 exit   pts/1    00:00:00 myprocess <defunct>

2. 向父进程发送SIGCHLD信号

$ kill -s SIGCHLD 1001

这将通知进程1001回收其子进程。

  1. 如果向父进程发送SIGCHLD信号后,僵尸进程仍未被清理,那么可以尝试杀死父进程。这样,僵尸进程将被init进程(PID为1)接管并自动清理。
    $ kill -s SIGTERM 1001
    

6. 实例分析

《How to Clean a Linux Zombie Process》 https://www.baeldung.com/linux/clean-zombie-process

7. 参考文档

https://www.geeksforgeeks.org/process-table-and-process-control-block-pcb/

相关文章:

聊聊僵尸进程

文章目录 1. 前言1.1 什么是僵尸进程1.2 为什么需要关注僵尸进程 2. 僵尸进程的产生2.2 为什么会产生僵尸进程2.3 举个栗子 3. 僵尸进程的影响3.1 僵尸进程为何会占用系统资源3.2 操作系统如何知道哪个资源需要被释放3.3 什么是进程表3.4 什么是PCB 5. 如何处理僵尸进程4.1 识别…...

stm32的时钟、中断的配置(针对寄存器),一些基础知识

一、学习参考资料 &#xff08;1&#xff09;正点原子的寄存器源码。 &#xff08;2&#xff09;STM32F103最小系统板开发指南-寄存器版本_V1.1&#xff08;正点&#xff09; &#xff08;3&#xff09;STM32F103最小系统板开发指南-库函数版本_V1.1&#xff08;正点&#xff0…...

Vue14 监视属性简写

监视属性简写 当监视属性只有handler时&#xff0c;可以使用简写 <!DOCTYPE html> <html><head><meta charset"UTF-8" /><title>天气案例_监视属性_简写</title><!-- 引入Vue --><script type"text/javascript&…...

基于docker+Keepalived+Haproxy高可用前后的分离技术

基于dockerKeepalivedHaproxy高可用前后端分离技术 架构图 服务名docker-ip地址docker-keepalived-vip-iphaproxy-01docker-ip自动分配 未指定ip192.168.31.252haproxy-02docker-ip自动分配 未指定ip192.168.31.253 安装haproxy 宿主机ip 192.168.31.254 宿主机keepalived虚…...

安装配置deep learning开发环境

1. 下载安装anacondahttps://www.anaconda.com/download-success vim ~/.condarcchannels: - bioconda - https://mirrors.ustc.edu.cn/anaconda/pkgs/main/ - https://mirrors.ustc.edu.cn/anaconda/cloud/conda-forge/ - https://mirrors.tuna.tsinghua.edu.cn/anaco…...

Docker基础(CentOS 7)

参考资料 hub.docker.com 查看docker官方仓库&#xff0c;需要梯子 Docker命令大全 黑马程序员docker实操教程 &#xff08;黑马讲的真的不错 容器与虚拟机 安装 yum install -y docker Docker服务命令 启动服务 systemctl start docker停止服务 systemctl stop docker重启…...

HTTP的基本格式

HTTP/HTTPS HTTPhttp的协议格式 HTTP 应用层,一方面是需要自定义协议,一方面也会用到一些现成的协议. HTTP协议,就是最常用到的应用层协议. 使用浏览器,打开网站,使用手机app,加载数据,这些过程大概率都是HTTP来支持的 HTTP是一个超文本传输协议, 文本>字符串 超文本>除…...

Qt元对象系统 day5

Qt元对象系统 day5 内存管理 QObject以对象树的形式组织起来&#xff0c;当为一个对象创建子对象时&#xff0c;子对象回自动添加到父对象的children()列表中。父对象拥有子对象所有权&#xff0c;比如父对象可以在自己的析构函数中删除它的孩子对象。使用findChild()或findC…...

【audio】alsa pcm音频路径

文章目录 AML方案音频路径分析dump alsa pcm各个音频路径的原始音频流数据 AML方案音频路径分析 一个Audio Patch用来表示一个或多个source端到一个或多个sink端。这个是从代码的注释翻译来的&#xff0c;大家可以把它比作大坝&#xff0c;可以有好几个入水口和出水口&#xf…...

NLP - 数据预处理 - 文本按句子进行切分

NLP - 数据预处理 - 文本按句子进行切分 文章目录 NLP - 数据预处理 - 文本按句子进行切分一、前言二、环境配置1、安装nltk库2、下载punkt分句器 三、运行程序四、额外补充 一、前言 在学习对数据训练的预处理的时候遇到了一个问题&#xff0c;就是如何将文本按句子切分&#…...

【轻松玩转MacOS】常用软件篇

引言 在本篇文章中&#xff0c;我将介绍如何安装和使用一些常用的软件&#xff0c;如Safari浏览器、邮件、日历、地图等。让我们一起来看看吧&#xff01; 一、Safari浏览器 Safari是MacOS自带的浏览器&#xff0c;具有简洁、快速、安全的特点。 以下是一些Safari浏览器的使…...

Akshare简记

文章目录 基本信息安装Anaconda安装(推荐)Anaconda设置AKShare安装使用AKShare更新数据接口一览数据字典用例Hello WorldMFI指标SMA指标BOLL线指标股市新闻情绪判断市场情绪指标ARBR条件选股回测配对交易策略日线策略计算相近产品基本信息 线上文档:...

Jmeter常用断言之断言持续时间简介

Duration Assertion&#xff1a;断言持续时间。 断言持续时间通常用于做性能测试&#xff0c;一般用于检查HTTP请求的响应时间是否超过预期值。而这个响应时间是性能测试中常关注的一个性能指标。 一、添加断言方式 根据需要可在【测试计划】、【线程组】、【线程请求】下添加…...

C/C++/VS2022/指针/数组 调试出现debug

这个情况就很难受&#xff0c;编译没错&#xff0c;但是运行出现问题了&#xff0c;如果点击中止&#xff08;重试、忽略&#xff09;下一次运行还是会出现&#xff0c;看了显示的大致意思是在数组arry上出现了什么错误&#xff0c;经过检查发现&#xff0c;原来是数组在数入时…...

【设计模式】使用原型模式完成业务中“各种O”的转换

文章目录 1.原型模式概述2.浅拷贝与深拷贝2.1.浅拷贝的实现方式2.2.深拷贝的实现方式 3.结语 1.原型模式概述 原型模式是一种非常简单易懂的模型&#xff0c;在书上的定义是这样的&#xff1a; Specify the kinds of objects to create using a prototypical instance,and cre…...

[C++ 网络协议] IOCP(Input Output Completion Port)

1.什么是IOCP IOCP&#xff08;Input Output Completion Port&#xff09;输入输出完成端口。其实就是基于重叠I/O的一种改进的模型。 重叠I/O具有缺点&#xff1a;重复调用非阻塞模式的accpet函数和以进入alertablewait状态为目的的SleepEx函数会影响程序性能。 而IOCP提供…...

R实现地图相关图形绘制

大家好&#xff0c;我是带我去滑雪&#xff01; 地图相关图形绘制具有许多优点&#xff0c;这些优点使其在各种领域和应用中非常有用。例如&#xff1a;地图相关图形提供了一种直观的方式来可视化数据&#xff0c;使数据更容易理解和分析。通过地图&#xff0c;可以看到数据的空…...

【Jmeter】性能测试脚本开发——性能测试环境准备、Jmeter脚本编写和执行

文章目录 一、常用的Jmeter元件二、性能测试环境准备三、编写Jmeter脚本四、执行测试脚本 一、常用的Jmeter元件 取样器-HTTP请求 作用&#xff1a;发送HTTP请求配置原件-HTTP请求默认值 作用&#xff1a;设置HTTP请求的默认参数配置原件-用户定义的变量 作用&#xff1a;定义…...

看好你家电视盒的后门!数千个Android电视盒感染了与欺诈相关的危险恶意软件

如果你从Android电视盒获得流媒体修复程序&#xff0c;则你的设备可能会被恶意软件所感染&#xff0c;这些恶意软件能够进行广告欺诈、创建假帐户&#xff0c;并通过悄悄地将你的数据转移到中国的服务器来销售对家庭网络的访问。 根据本周的一份新报告&#xff0c;网络安全公司…...

LeetCode 1251. 平均售价

题目链接&#xff1a;1251. 平均售价 题目描述 表&#xff1a;Prices Column NameTypeproduct_idintstart_datedateend_datedatepriceint (product_id&#xff0c;start_date&#xff0c;end_date) 是 prices 表的主键&#xff08;具有唯一值的列的组合&#xff09;。 price…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...