创建僵尸进程
Posted
技术标签:
【中文标题】创建僵尸进程【英文标题】:Create zombie process 【发布时间】:2014-09-30 02:22:55 【问题描述】:我有兴趣创建一个僵尸进程。据我了解,僵尸进程发生在父进程在子进程之前退出时。但是,我尝试使用以下代码重新:
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main ()
pid_t child_pid;
child_pid = fork ();
if (child_pid > 0)
exit(0);
else
sleep(100);
exit (0);
return 0;
但是,此代码在预期执行后立即退出。但是,和我一样
ps aux | grep a.out
我发现 a.out 只是作为正常进程运行,而不是我预期的僵尸进程。
我使用的操作系统是 ubuntu 14.04 64 位
【问题讨论】:
您问题中的代码不会,因为在您的代码中,父进程首先退出,而子进程继续运行。 (请记住,fork() 在子进程中返回 0,在父进程中返回子进程的 PID。)要查看僵尸进程,您需要在父进程还活着但没有等待子进程时让子进程退出。如果您只是将代码的第 10 行从if (child_pid > 0)
更改为 if (child_pid == 0)
,它将“修复”您的代码,并且当子进程退出时您将能够看到僵尸进程。
【参考方案1】:
引用:
据我了解,僵尸进程发生在父进程在子进程之前退出时。
这是错误的。根据man 2 wait
(见注释):
终止但没有等待的孩子变成了“僵尸”。
所以,如果你想创建一个僵尸进程,在fork(2)
之后,子进程应该exit()
,父进程在退出之前应该sleep()
,让你有时间观察@的输出987654326@.
例如,您可以使用下面的代码代替您的代码,并使用ps(1)
而sleep()
ing:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
pid_t pid;
int status;
if ((pid = fork()) < 0)
perror("fork");
exit(1);
/* Child */
if (pid == 0)
exit(0);
/* Parent
* Gives you time to observe the zombie using ps(1) ... */
sleep(100);
/* ... and after that, parent wait(2)s its child's
* exit status, and prints a relevant message. */
pid = wait(&status);
if (WIFEXITED(status))
fprintf(stderr, "\n\t[%d]\tProcess %d exited with status %d.\n",
(int) getpid(), pid, WEXITSTATUS(status));
return 0;
【讨论】:
非常感谢 chrk!我试过你的代码,我看到了一些僵尸进程。但我还有一个担忧。为什么我的代码没有创建僵尸进程?根据您帖子中的定义,子进程是否在没有被父进程等待的情况下退出(父进程已在没有等待命令的情况下退出)。 @chrk @user3354832 您在问题中的代码不会创建僵尸进程,因为在您的代码中,父进程首先退出,而子进程继续运行。 (请记住,fork() 在子进程中返回 0,在父进程中返回子进程的 PID。)要查看僵尸进程,您需要在父进程还活着但没有等待子进程时让子进程退出。如果您只是将代码的第 10 行从if (child_pid > 0)
更改为 if (child_pid == 0)
,它将“修复”您的代码,并且您将能够在子进程退出时看到僵尸进程。
只是为了详细说明。如果父级先退出,则子级现在是孤儿(其父级死亡),init 进程将采用它(因此新父级为 pid 1)。 init 进程注册了一个特殊的处理程序,以便在子进程死亡时收到通知,因此当子进程死亡时,它将等待它读取其状态码,因此子进程不会成为僵尸进程。如果 init 进程不这样做(例如在 docker 中运行时很常见),那么您的版本仍然会有僵尸。【参考方案2】:
Linux 中的僵尸或“失效进程”是指已经完成的进程,但由于父子进程之间缺乏对应关系,它的条目仍保留在进程表中。通常,父进程通过 wait() 函数检查其子进程的状态。当子进程完成时,等待函数向父进程发出信号以完全退出内存中的进程。但是,如果父进程未能为其任何子进程调用等待函数,则子进程在系统中仍作为死进程或僵尸进程保持活动状态。这些僵尸进程可能会在您的系统上大量堆积并影响其性能。
下面是一个在我们系统上创建僵尸进程的c程序将此文件保存为zombie.c:
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main ()
pid_t child_pid;
child_pid = fork ();
if (child_pid > 0)
sleep (60);
else
exit (0);
return 0;
通过此代码创建的僵尸进程将运行 60 秒。您可以通过在 sleep() 函数中指定时间(以秒为单位)来增加持续时间。
编译这个程序
gcc zombie.c
现在运行僵尸程序:
./a.out
ps 命令现在也会显示这个已失效的进程,打开一个新终端并使用以下命令检查已失效的进程:
aamir@aamir:~/process$ ps -ef | grep a.out
aamir 10171 3052 0 17:12 pts/0 00:00:00 ./a.out
aamir 10172 10171 0 17:12 pts/0 00:00:00 [a.out] <defunct> #Zombie process
aamir 10177 3096 0 17:12 pts/2 00:00:00 grep --color=auto a.out
【讨论】:
以上是关于创建僵尸进程的主要内容,如果未能解决你的问题,请参考以下文章