fbpx
维基百科

僵尸进程

类UNIX系统中,僵尸进程是指完成执行(通过exit系统调用,或运行时发生致命错误或收到终止信号所致),但在操作系统的进程表中仍然存在其进程控制块,处于"终止状态英语Process state#Terminated"的进程。这发生于子进程需要保留表项以允许其父进程读取子进程的退出狀態:一旦退出态通过wait系统调用读取,僵尸进程条目就从进程表中删除,称之为"回收"(reaped)。正常情况下,进程直接被其父进程wait并由系统回收。进程长时间保持僵尸状态一般是错误的并导致资源泄漏

「僵尸进程」的各地常用別名
中国大陸僵尸进程
臺灣殭屍行程
港澳殭屍行程

英文术语zombie process源自喪屍——不死之人,隐喻子进程已死但仍然没有被回收。与正常进程不同,kill命令对僵尸进程无效。孤儿进程不同于僵尸进程,其父进程已经死掉,但孤儿进程仍能正常执行,但并不会变为僵尸进程,因为被init(进程ID号为1)收养并wait其退出。

子进程死后,系统会发送SIGCHLD信号给父进程,父进程对其默认处理是忽略。如果想响应这个消息,父进程通常在信号事件处理程序中,使用wait系统调用来响应子进程的终止。

僵尸进程被回收后,其进程号与在进程表中的表项都可以被系统重用。但如果父进程没有调用wait,僵尸进程将保留进程表中的表项,导致了资源泄漏。某些情况下这反倒是期望的:父进程创建了另外一个子进程,并希望具有不同的进程号。如果父进程通过设置事件处理函数为SIG_IGN显式忽略SIGCHLD信号,而不是隐式默认忽略该信号,或者具有SA_NOCLDWAIT标志,所有子进程的退出状态信息将被抛弃并且直接被系统回收。

UNIX命令ps列出的进程的状态("STAT")栏标示为 "Z"则为僵尸进程。[1]

收割僵尸进程的方法是通过kill命令手工向其父进程发送SIGCHLD信号。如果其父进程仍然拒绝收割僵尸进程,则终止父进程,使得init进程收养僵尸进程。init进程周期执行wait系统调用收割其收养的所有僵尸进程。

为避免产生僵尸进程,实际应用中一般采取的方式是:

  1. 将父进程中对SIGCHLD信号的处理函数设为SIG_IGN(忽略信号);
  2. fork两次并杀死一级子进程,令二级子进程成为孤儿进程而被init所“收养”、清理[2]

例子

#include <sys/wait.h> #include <stdlib.h> #include <unistd.h> int main(void) {  pid_t pids[10];  int i;  for (i = 9; i >= 0; --i) {  pids[i] = fork();  if (pids[i] == 0) {  sleep(i+1);  _exit(0);  }  }  for (i = 9; i >= 0; --i)  waitpid(pids[i], NULL, 0);  return 0; } 

参见

  • Fork炸弹
  • Zombie object英语Zombie object

参考文献

  1. ^ Zombies(5) - UNIX System V (Concepts). The Collider Detector at Fermilab. [2014-05-24]. (原始内容于2020-11-09). 
  2. ^ UNIX环境高级编程Advanced Programming in the UNIX Environment),理查德·史蒂文斯著,1992,ISBN 0-201-56317-7
  • . UNIXhelp for Users. [2014-05-24]. (原始内容存档于2013-03-08). 

外部链接

  • Zombie process usenet post (页面存档备份,存于互联网档案馆
  • UNIX FAQ Question 3.13: How do I get rid of zombie processes that persevere? (页面存档备份,存于互联网档案馆

僵尸进程, 在类unix系统中, 是指完成执行, 通过exit系统调用, 或运行时发生致命错误或收到终止信号所致, 但在操作系统的进程表中仍然存在其进程控制块, 处于, 终止状态, 英语, process, state, terminated, 的进程, 这发生于子进程需要保留表项以允许其父进程读取子进程的退出狀態, 一旦退出态通过, href, wait, unix, html, title, wait, unix, wait, 系统调用读取, 条目就从进程表中删除, 称之为, 回收, reaped, 正常情况下. 在类UNIX系统中 僵尸进程是指完成执行 通过exit系统调用 或运行时发生致命错误或收到终止信号所致 但在操作系统的进程表中仍然存在其进程控制块 处于 终止状态 英语 Process state Terminated 的进程 这发生于子进程需要保留表项以允许其父进程读取子进程的退出狀態 一旦退出态通过 a href Wait Unix html title Wait Unix wait a 系统调用读取 僵尸进程条目就从进程表中删除 称之为 回收 reaped 正常情况下 进程直接被其父进程wait并由系统回收 进程长时间保持僵尸状态一般是错误的并导致资源泄漏 僵尸进程 的各地常用別名中国大陸僵尸进程臺灣殭屍行程港澳殭屍行程英文术语zombie process源自喪屍 不死之人 隐喻子进程已死但仍然没有被回收 与正常进程不同 a href Kill E5 91 BD E4 BB A4 html title Kill 命令 kill a 命令对僵尸进程无效 孤儿进程不同于僵尸进程 其父进程已经死掉 但孤儿进程仍能正常执行 但并不会变为僵尸进程 因为被 a href Init html title Init init a 进程ID号为1 收养并wait其退出 子进程死后 系统会发送SIGCHLD信号给父进程 父进程对其默认处理是忽略 如果想响应这个消息 父进程通常在信号事件处理程序中 使用wait系统调用来响应子进程的终止 僵尸进程被回收后 其进程号与在进程表中的表项都可以被系统重用 但如果父进程没有调用wait 僵尸进程将保留进程表中的表项 导致了资源泄漏 某些情况下这反倒是期望的 父进程创建了另外一个子进程 并希望具有不同的进程号 如果父进程通过设置事件处理函数为SIG IGN显式忽略SIGCHLD信号 而不是隐式默认忽略该信号 或者具有SA NOCLDWAIT标志 所有子进程的退出状态信息将被抛弃并且直接被系统回收 UNIX命令 a href Ps Unix html title Ps Unix ps a 列出的进程的状态 STAT 栏标示为 Z 则为僵尸进程 1 收割僵尸进程的方法是通过kill命令手工向其父进程发送SIGCHLD信号 如果其父进程仍然拒绝收割僵尸进程 则终止父进程 使得init进程收养僵尸进程 init进程周期执行wait系统调用收割其收养的所有僵尸进程 为避免产生僵尸进程 实际应用中一般采取的方式是 将父进程中对SIGCHLD信号的处理函数设为SIG IGN 忽略信号 fork两次并杀死一级子进程 令二级子进程成为孤儿进程而被init所 收养 清理 2 目录 1 例子 2 参见 3 参考文献 4 外部链接例子 编辑 include lt sys wait h gt include lt stdlib h gt include lt unistd h gt int main void pid t pids 10 int i for i 9 i gt 0 i pids i fork if pids i 0 sleep i 1 exit 0 for i 9 i gt 0 i waitpid pids i NULL 0 return 0 参见 编辑Fork炸弹 Zombie object 英语 Zombie object 参考文献 编辑 Zombies 5 UNIX System V Concepts The Collider Detector at Fermilab 2014 05 24 原始内容存档于2020 11 09 UNIX环境高级编程 Advanced Programming in the UNIX Environment 理查德 史蒂文斯著 1992 ISBN 0 201 56317 7 UNIX man pages ps UNIXhelp for Users 2014 05 24 原始内容存档于2013 03 08 外部链接 编辑Zombie process usenet post 页面存档备份 存于互联网档案馆 UNIX FAQ Question 3 13 How do I get rid of zombie processes that persevere 页面存档备份 存于互联网档案馆 取自 https zh wikipedia org w index php title 僵尸进程 amp oldid 75020186, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。