僵尸进程(Zombie Process) 和 孤儿进程(Orphan Process)详解
在 Linux 系统中,僵尸进程(Zombie Process) 和 孤儿进程(Orphan Process) 是进程生命周期中的两种特殊状态,由父子进程的生命周期不同步导致。它们对系统稳定性和资源管理有重要影响,以下是详细解析:
⚙️ 一、定义与核心概念
僵尸进程(Zombie Process)
- 定义:子进程已终止(通过
exit()结束运行),但其父进程未调用wait()或waitpid()回收其退出状态,导致内核保留子进程的进程描述符(PID、退出码、资源统计等)。 - 状态标识:在
ps或top命令中显示为 Z(Zombie)。
- 定义:子进程已终止(通过
孤儿进程(Orphan Process)
- 定义:父进程先于子进程终止(如崩溃或被杀死),子进程失去父进程,此时内核将其移交 init 进程(PID=1)接管(如 systemd 或传统 init)。
- 状态:正常运行,但父进程 ID(PPID)变为 1。
| 类型 | 触发条件 | 系统处理方式 | 进程状态 |
|---|---|---|---|
| 僵尸进程 | 子进程结束,父进程未调用 wait | 保留进程表项等待父进程回收 | Z (僵尸) |
| 孤儿进程 | 父进程结束,子进程仍在运行 | 由 init 进程(PID=1)接管并回收资源 | 正常运行 |
二、形成原因
僵尸进程的成因:
父进程未回收子进程:父进程未调用
wait()系列函数,或未处理SIGCHLD信号(子进程退出时内核发送的信号)。编程错误:父进程设计缺陷(如忽略子进程退出逻辑)。
父进程阻塞:父进程忙于其他任务,未及时响应子进程退出。
孤儿进程的成因:
父进程意外终止:如程序崩溃、被
kill命令强制结束。父进程主动退出未等待子进程:父进程未通过
wait()同步子进程结束。
️ 三、对操作系统的危害
僵尸进程的危害:
- 资源泄漏:占用进程表项(每个僵尸进程消耗一个 PID),若大量积累,耗尽 PID 空间(上限由
/proc/sys/kernel/pid_max设定),导致系统无法创建新进程。 - 内存与内核资源占用:保留退出状态、资源统计信息,可能占用内核内存页表。
- 干扰监控工具:影响
ps、top等工具的准确性。
- 资源泄漏:占用进程表项(每个僵尸进程消耗一个 PID),若大量积累,耗尽 PID 空间(上限由
孤儿进程的危害:
- 几乎无害:由 init 进程自动接管并调用
wait()回收资源,不会长期占用资源。 - 资源占用短暂:仅在运行期间消耗 CPU/内存,退出后立即被 init 清理。
- 几乎无害:由 init 进程自动接管并调用
关键区别:僵尸进程是 “已死未葬”(资源未回收),孤儿进程是 “无父被收养”(由 init 妥善管理)。
️ 四、解决方案
僵尸进程的解决方法:
父进程调用
wait()/waitpid():
确保父进程阻塞等待子进程结束并回收资源。pid_t pid = fork();
if (pid == 0) exit(0); // 子进程退出
else wait(NULL); // 父进程回收
处理
SIGCHLD信号:
注册信号处理函数,异步回收子进程(需循环调用waitpid防止漏处理)。void sigchld_handler(int sig) {
while (waitpid(-1, NULL, WNOHANG) > 0); // 非阻塞回收所有僵尸进程
}
signal(SIGCHLD, sigchld_handler);
忽略
SIGCHLD信号:
通过signal(SIGCHLD, SIG_IGN)通知内核自动清理子进程,无需父进程等待。双重 fork 技巧:
创建孙进程执行任务,子进程立即退出,孙进程由 init 接管,避免父进程直接管理。pid_t pid = fork();
if (pid == 0) {
if (fork() == 0) execve(...); // 孙进程执行任务
else exit(0); // 子进程退出
}
waitpid(pid, NULL, 0); // 父进程回收子进程
终止父进程:
若僵尸进程已积累,杀死其父进程(kill -HUP <PPID>),僵尸进程转为孤儿进程后被 init 清理。
孤儿进程的解决方法:
- 无需干预:init 进程自动回收,开发者仅需确保父进程异常时子进程能正常结束。
五、总结
僵尸进程是严重的资源泄漏源,需通过代码规范(
wait()/信号处理)或系统管理(杀父进程)解决。孤儿进程是临时状态,由 init 进程兜底管理,不影响系统稳定性。
最佳实践:多进程程序中,父进程必须实现子进程状态回收逻辑,或使用进程池集中管理生命周期。
僵尸进程(Zombie Process) 和 孤儿进程(Orphan Process)详解的更多相关文章
- Spring Boot 2.x基础教程:进程内缓存的使用与Cache注解详解
随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决这一问题非常好的手段之一.Spring 3开始提供了强大的基于注解的缓 ...
- linux系统编程之进程(三):进程复制fork,孤儿进程,僵尸进程
本节目标: 复制进程映像 fork系统调用 孤儿进程.僵尸进程 写时复制 一,进程复制(或产生) 使用fork函数得到的子进程从父进程的继承了整个进程的地址空间,包括:进程上下文.进程堆栈. ...
- 进程、线程与GIL全局解释器锁详解
进程与线程的关系: . 线程是最小的调度单位 . 进程是最小的管理单元 . 一个进程必须至少一个线程 . 没有线程,进程也就不复存在 线程特点: 线程的并发是利用cpu上下文的切换(是并发,不是并行) ...
- Linux如何让进程在后台运行的三种方法详解
问题分析: 我们知道,当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程.因此,我们的解决办法就有两种途径:要么让进程忽略 HUP 信号,要么让进程运 ...
- 并发编程(二)--利用Process类开启进程、僵尸进程、孤儿进程、守护进程、互斥锁、队列与管道
一.multiprocessing模块 1.multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似. 2.mu ...
- 并发编程(二)——利用Process类开启进程、僵尸进程、孤儿进程、守护进程、互斥锁、队列与管道
Process类与开启进程.守护进程.互斥锁 一.multiprocessing模块 1.multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模 ...
- 僵尸进程(zombie process)
首先了解一下linux中进程的5大状态: R Running or runnable (on run queue)S Interruptible sleep (waiting for an event ...
- OS之进程管理---孤儿进程和僵尸进程
僵尸进程 当一个进程终止时,操作系统会释放其资源,不过它位于进程表中的条目还是在的,直到它的父进程调用wait():这是因为进程表中包含了进程的退出状态.当进程已经终止,但是其父进尚未调用wait() ...
- Go Exec 僵尸与孤儿进程
原文地址:Go Exec 僵尸与孤儿进程 最近,使用 golang 去管理本地应用的生命周期,期间有几个有趣的点,今天就一起看下. 场景一 我们来看看下面两个脚本会产生什么问题: 创建两个 shell ...
- [Linux] 孤儿进程与僵尸进程[总结]
转载: http://www.cnblogs.com/Anker/p/3271773.html 1.前言 之前在看<unix环境高级编程>第八章进程时候,提到孤儿进程和僵尸进程,一直对这两 ...
随机推荐
- C++11 auto和decltype关键字
今天来看下C++中的auto和decltype两个关键字 auto关键字定义变量,编译器会自动判断变量的类型 举个栗子: auto i =100; // i 是 int auto p = new A( ...
- 1-2 【包子mysql系列】, 对mysql的innoDB加锁分析
innoDB的事务,是基于锁来实现的,用到事务不自然就会用到锁,而如果对锁理解的不通透,很容易造成线上问题. 数据库加锁的分析,和事务的引擎,隔离级别,索引,主键索引都有关系, 如果去考虑引擎和各种隔 ...
- 企业为何要使用odoo18
在当今快速变化的商业环境中,企业需要高效.灵活且经济实惠的管理工具来保持竞争力.Odoo 18 作为一款开源的企业资源计划(ERP)系统,凭借其全面的功能和独特的优势,成为众多企业的首选. 为什么选择 ...
- Web前端入门第 61 问:JavaScript 各种对象定义与对象取值方法
曾经有人说 JS 语言中万物皆对象,虽然这种说法不一定完全准确,但也有一定的道理.原因是 JS 的语法看起来所有的数据类型都像是一个对象,包括原始类型. const a = 1.234; consol ...
- 「Log」CSP-S 2023 游记
Day 0 什么题也没写,稍微复习了一下,晚上打了些板子. 整个人处于放空状态. Day 1 早上睡了懒觉,老爹早就给我点了肯德基早餐. 边吃早餐边看番,吃完了去群里水了一水,讨论了点杂七杂八的东西, ...
- 「Log」2023.8.14 小记
序幕 起晚了,七点半到校. 跟化竞选手寒暄几句之后就去开电脑. 补周末没写的博客,补落下的题单. 学杜教筛??????不会卷积????? 暂时放弃,学一下扩欧. 写了篇扩欧博客. \(\text{Li ...
- MyBatisPlus笔记(高级)
MyBatisPlus(高级) 作者:故事我忘了¢个人微信公众号:程序猿的月光宝盒 目录 MyBatisPlus(高级) 说明: 相关连接: 慕课入门视频: 入门文章: 本文对应进阶视频: 整合的gi ...
- Java IO<5>管道流PipedOutputStream PipedInputStream
在java中,PipedOutputStream和PipedInputStream分别是管道输出流和管道输入流.它们的作用是让多线程可以通过管道进行线程间的通讯.在使用管道通信时,必须将PipedOu ...
- 记录.Net 8 发布增加 PublishTrimmed 裁剪选项,调用WMI 的ManagementObject 异常
最近在做OTA的功能,需要获取到sn做一些业务的逻辑.我们自己实现的库里边的,大部分都是调用 System.Management 的 ManagementObjectSearcher 获取 Bios ...
- 《Building REST APIs with Flask》读后感
一. 为什么读这本书? 之所以选择这本书其实是因为最近自己在梳理 JWT 的用法.自己曾参与过的一个项目虽然使用的是 Flask 开发,但是授权使用的 PyJWT,当时以为使用 PyJWT 是行业通用 ...