linux僵尸进程理解,聊聊Linux系统中的僵尸进程
车祸现场
今天下午,笔者正在认真搬砖,日志集群中有一台机器忽然报init进程占用100% CPU。strace之,发现疯狂输出如下系统调用。
~ strace -p 1
rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f7cc15789d0) = -1 ENOMEM (Cannot allocate memory)
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
close(9) = 0
close(10) = 0
pipe([9, 10]) = 0
rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f7cc15789d0) = -1 ENOMEM (Cannot allocate memory)
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
close(9) = 0
close(10) = 0
pipe([9, 10]) = 0
rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f7cc15789d0) = -1 ENOMEM (Cannot allocate memory)
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
close(9) = 0
close(10) = 0
pipe([9, 10]) = 0
然后top和ps发现大量PPID为1的僵尸进程,说明init进程不知为何不再回收僵尸进程了。
原因未查明(高度怀疑CentOS 6系统/内核bug,或是硬件问题?下图是查找到的一种可能性),并且僵尸进程还在不断增多,急呼运维同学reboot,遂恢复正常。
折腾了半天,今晚简单说说僵尸进程吧。
僵尸进程、产生原因及危害
"zombie process"或者"defunct process",是类Unix系统中的概念,指那些实际运行已经完成或终止[如通过exit()系统调用,或者发生错误、收到终止信号],但是在系统进程表中仍然残留着对应的进程项,没有完全被清理的进程。僵尸进程已经释放了除进程表项外的所有内存空间,无法再被调度执行,只是在等待其他进程来收集它的退出状态信息而已。
在正常情况下,父进程会通过wait()或waitpid()系统调用进行善后处理,即获取其子进程的退出状态。一旦成功获取,该僵尸子进程就会被销毁(reaped)而不复存在,其进程表项也会被释放。所以子进程退出时,应该只会在exit()和wait()之间很短暂地处于僵尸状态。
但是,如果父进程没有通过wait()或waitpid()系统调用获取其子进程的退出状态,也没有显式地处理或者忽略掉SIGCHLD信号[该信号是子进程结束时发送给父进程的],并且父进程保持运行,那么它的子进程结束后就一直处于僵尸状态了,此时就可以被用户观察到。在top命令下,僵尸进程的状态会显示为"Z",在ps命令下则会带上""标记。
很显然,如果僵尸进程一直不被销毁,那么它们将永远占用PID和进程表中的空间。Linux系统中的PID取值范围是有限制的(在/proc/sys/kernel/pid_max下,默认值32768),过多的僵尸进程会导致系统PID耗尽,无法再创建新的进程。
如何手动清理?
僵尸进程是无法被直接kill掉的,而造成僵尸进程无法销毁的罪魁祸首是它的父进程不做善后工作。所以,我们可以通过kill命令发送SIGKILL/SIGTERM信号直接干掉父进程,它的子进程就会成为所谓“孤儿进程”(orphan process)。孤儿进程会被根进程init收养,并且init进程会在后台执行wait()或waitpid()系统调用,代替它们的父进程完成清理工作。
但是在极端情况下,仍然有可能出现init出现大量僵尸子进程的情况(比如本文开头),这时就只能干掉init进程——即重启系统了。
如何避免?
父进程一定要尽职尽责,避免出现长时间僵尸进程的方法有:
在signal()系统调用中设定SIGCHLD信号的handler回调,并显式wait()处理之。
在signal()系统调用中设定handler为SIG_IGN,即显式忽略该信号,子进程的回收会由内核直接负责。
在产生子进程时做两次fork(),并立即杀掉一级子进程,令二级子进程(即真正的子进程)成为孤儿并被init收养。没那么“负责任”,但是也比较安全。
The End
民那晚安晚安。
linux僵尸进程理解,聊聊Linux系统中的僵尸进程相关推荐
- .gpg 进程 linux,小知识之Linux系统中的最大进程数,最大文件描述,最大线程数...
今天来了解一下linux里面的一些小知识: (一)Linux系统中最大可以起多少个进程? (1)32位系统中最多可以起32768个进程 (2)64位系统中最多可以起2的22次方(4194304)约42 ...
- linux查看pid对应的进程,linux系统中快速查看进程pid的方法
linux系统中快速查看进程pid的方法 一个很简单的'命令,pgrep,可以迅速定位包含某个关键字的进程的pid:使用这个命令,再也不用ps aux 以后去对哪个进程的pid了 用法: pgrep ...
- 消息中间件解析 | 如何正确理解软件应用系统中关于系统通信的那些事?
苍穹之边,浩瀚之挚,眰恦之美:悟心悟性,善始善终,惟善惟道! -- 朝槿<朝槿兮年说> 写在开头 随着业务需求的发展和用户数量的激增,对于互联网应用系统或者服务应用程序则提出了新的挑战,也 ...
- 遍历系统中所有的进程,可根据名字或ID查找某一个线程
我们这根据名字查找进程,获取其ID 1 /*@brief 获取找到的与指定进程名相符的第一个进程ID 2 * @param [in] cpszExeFileName 进程可执行文件名(不带路径) 3 ...
- 【Android 逆向】修改运行中的 Android 进程的内存数据 ( Android 系统中调试器进程内存流程 | 编译内存调试动态库以及调试程序 )
文章目录 一.Android 系统中调试器进程内存流程 二.编译内存调试动态库以及调试程序 三.博客资源 一.Android 系统中调试器进程内存流程 修改游戏运行中的内存 , 游戏运行之后 , 游戏 ...
- 16进制 ksh_AIX系统中如何统计进程打开的文件数目
作者:李烨楠 中国建设银行 来自微信公众号:平台人生 环境: AIX 6.1 AIX7.1 前言: 用户有时需要统计一个进程打开的文件数目,比如,在当前打开文件句柄使用量是否超过用户资源限制(/etc ...
- Windows系统中常见的进程DOS操作命令
Windows系统中常见的进程DOS操作命令 1. 查看指定端口的占用情况 语法: netstat -aon | findstr 端口号 例如:查看目前已经启动的nginx进程号 netstat -a ...
- 【详细解读】进程管理 -死锁问题 系统有三个进程:A B C 这3个进程都需要5个系统资源。如果系统至少有多少个资源,则不可能发生死锁
进程管理 -死锁问题 系统有三个进程:A B C 这3个进程都需要5个系统资源.如果系统至少有多少个资源,则不可能发生死锁? 最多的状态是:每个进程恰好都分到了四个资源, 都只需要一个资源就可以运行, ...
- java defunct怎么杀掉_僵尸进程的产生和避免,如何kill杀掉linux系统中的僵尸defunct进程...
在 Unix系统管理中,当用ps命令观察进程的执行状态时,经常看到某些进程的状态栏为defunct,这就是所谓的"僵尸"进程."僵尸"进程是一个早已 死亡的进程 ...
最新文章
- 怎样使用dhcp自动分配IP地址
- 与癌症作战的 12 家 AI 公司,八仙过海各显神通
- 介绍一种导入文件夹中图片数据集的方法
- 感知器 Perceptron
- java des加密解密_JAVA和c# 之间数据通讯时通过DES进行加密解密
- 他们是最懂数据的商家!智能品牌时代到来
- 依赖注入的细节_value子标签_特殊字符的注入
- win7计算机双击空白,win7系统控制面板“打开或关闭Windows 功能”空白没有任何选项的解决方法...
- spring-mvc默认首页配置
- SimpleDateFormat关于时间类的一些常用处理
- 20145237 Exp2 后门原理与实践
- python制作个人名片_python做名片系统
- 回答一个关于产品经理的入门门槛高不高的问题
- Excel 技术篇-使用excel启用宏提示:“可能是因为该宏在此工作簿中不可用,或者所有的宏都被禁用“问题解决方法
- 三村合建水厂问题研究
- CocosCreator接入穿山甲SDK(IOS)--激励视屏
- Vue | 指令实现自动填充英文名功能
- 51单片机按键消抖方式总结
- 从零开始学VUE之IDEA安装VUE插件
- A ResourcePool could not acquire a resource from its primary factory or source异常解决