车祸现场

今天下午,笔者正在认真搬砖,日志集群中有一台机器忽然报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系统中的僵尸进程相关推荐

  1. .gpg 进程 linux,小知识之Linux系统中的最大进程数,最大文件描述,最大线程数...

    今天来了解一下linux里面的一些小知识: (一)Linux系统中最大可以起多少个进程? (1)32位系统中最多可以起32768个进程 (2)64位系统中最多可以起2的22次方(4194304)约42 ...

  2. linux查看pid对应的进程,linux系统中快速查看进程pid的方法

    linux系统中快速查看进程pid的方法 一个很简单的'命令,pgrep,可以迅速定位包含某个关键字的进程的pid:使用这个命令,再也不用ps aux 以后去对哪个进程的pid了 用法: pgrep ...

  3. 消息中间件解析 | 如何正确理解软件应用系统中关于系统通信的那些事?

    苍穹之边,浩瀚之挚,眰恦之美:悟心悟性,善始善终,惟善惟道! -- 朝槿<朝槿兮年说> 写在开头 随着业务需求的发展和用户数量的激增,对于互联网应用系统或者服务应用程序则提出了新的挑战,也 ...

  4. 遍历系统中所有的进程,可根据名字或ID查找某一个线程

    我们这根据名字查找进程,获取其ID 1 /*@brief 获取找到的与指定进程名相符的第一个进程ID 2 * @param [in] cpszExeFileName 进程可执行文件名(不带路径) 3 ...

  5. 【Android 逆向】修改运行中的 Android 进程的内存数据 ( Android 系统中调试器进程内存流程 | 编译内存调试动态库以及调试程序 )

    文章目录 一.Android 系统中调试器进程内存流程 二.编译内存调试动态库以及调试程序 三.博客资源 一.Android 系统中调试器进程内存流程 修改游戏运行中的内存 , 游戏运行之后 , 游戏 ...

  6. 16进制 ksh_AIX系统中如何统计进程打开的文件数目

    作者:李烨楠 中国建设银行 来自微信公众号:平台人生 环境: AIX 6.1 AIX7.1 前言: 用户有时需要统计一个进程打开的文件数目,比如,在当前打开文件句柄使用量是否超过用户资源限制(/etc ...

  7. Windows系统中常见的进程DOS操作命令

    Windows系统中常见的进程DOS操作命令 1. 查看指定端口的占用情况 语法: netstat -aon | findstr 端口号 例如:查看目前已经启动的nginx进程号 netstat -a ...

  8. 【详细解读】进程管理 -死锁问题 系统有三个进程:A B C 这3个进程都需要5个系统资源。如果系统至少有多少个资源,则不可能发生死锁

    进程管理 -死锁问题 系统有三个进程:A B C 这3个进程都需要5个系统资源.如果系统至少有多少个资源,则不可能发生死锁? 最多的状态是:每个进程恰好都分到了四个资源, 都只需要一个资源就可以运行, ...

  9. java defunct怎么杀掉_僵尸进程的产生和避免,如何kill杀掉linux系统中的僵尸defunct进程...

    在 Unix系统管理中,当用ps命令观察进程的执行状态时,经常看到某些进程的状态栏为defunct,这就是所谓的"僵尸"进程."僵尸"进程是一个早已 死亡的进程 ...

最新文章

  1. 怎样使用dhcp自动分配IP地址
  2. 与癌症作战的 12 家 AI 公司,八仙过海各显神通
  3. 介绍一种导入文件夹中图片数据集的方法
  4. 感知器 Perceptron
  5. java des加密解密_JAVA和c# 之间数据通讯时通过DES进行加密解密
  6. 他们是最懂数据的商家!智能品牌时代到来
  7. 依赖注入的细节_value子标签_特殊字符的注入
  8. win7计算机双击空白,win7系统控制面板“打开或关闭Windows 功能”空白没有任何选项的解决方法...
  9. spring-mvc默认首页配置
  10. SimpleDateFormat关于时间类的一些常用处理
  11. 20145237 Exp2 后门原理与实践
  12. python制作个人名片_python做名片系统
  13. 回答一个关于产品经理的入门门槛高不高的问题
  14. Excel 技术篇-使用excel启用宏提示:“可能是因为该宏在此工作簿中不可用,或者所有的宏都被禁用“问题解决方法
  15. 三村合建水厂问题研究
  16. CocosCreator接入穿山甲SDK(IOS)--激励视屏
  17. Vue | 指令实现自动填充英文名功能
  18. 51单片机按键消抖方式总结
  19. 从零开始学VUE之IDEA安装VUE插件
  20. A ResourcePool could not acquire a resource from its primary factory or source异常解决

热门文章

  1. 一网打尽!每个程序猿都该了解的黑客技术大汇总
  2. 基础Git操作与GitHub协作吐血整理,收好!| 原力计划
  3. CNN vs RNN vs ANN——3 种神经网络分析模型,你 Pick 谁?
  4. 小米上市 365 天:雷军的坚守与败退
  5. 微信说不!有何不可?
  6. 软件工程师如何笑着活下去?
  7. 漫画 | 为什么 MySQL 数据库要用 B+ 树存储索引?
  8. 程序员如何 Get 分布式锁的正确姿势?| 技术头条
  9. 2017 开发者大调查活动获奖名单新鲜出炉
  10. 二叉树+链表+字符串+栈和队列高频面试题合集