我有兴趣创建一个僵尸进程。根据我的理解,当父进程在子进程之前退出时,就会发生僵尸进程。但是,我尝试使用以下代码重新创建僵尸进程:
#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位
答案 0 :(得分:17)
引用:
根据我的理解,当父进程在子进程处理之前退出时,就会发生僵尸进程。
这是错误的。根据{{3}}(见注释):
终止但未等待的孩子会成为&#34;僵尸&#34;。
所以,如果你想在fork(2)
之后创建一个僵尸进程,那么子进程应该exit()
,并且父进程应该sleep()
才能退出,给你时间观察ps(1)
的输出。
例如,您可以使用下面的代码代替您的代码,并在ps(1)
时使用sleep()
:
#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;
}
答案 1 :(得分:0)
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