创建僵尸进程

use*_*832 15 c linux operating-system fork zombie-process

我有兴趣创建一个僵尸进程.根据我的理解,当父进程在子进程之前退出时,就会发生僵尸进程.但是,我尝试使用以下代码重新创建僵尸进程:

#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;
}
Run Code Online (Sandbox Code Playgroud)

但是,此代码在执行后立即退出,这是预期的.但是,就像我一样

ps aux | grep a.out
Run Code Online (Sandbox Code Playgroud)

我发现a.out只是作为一个正常的进程运行,而不是像我预期的那样的僵尸进程.

我使用的操作系统是ubuntu 14.04 64位

chr*_*hrk 18

引用:

根据我的理解,当父进程在子进程之前退出时,就会发生僵尸进程.

这是错的.根据man 2 wait(参见注释):

终止但尚未等待的孩子变成了"僵尸".

因此,如果你想创建一个僵尸进程,那么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;
}
Run Code Online (Sandbox Code Playgroud)

  • @user3354832问题中的代码不会创建僵尸进程,因为在您的代码中,父进程首先退出,而子进程继续运行。(记住 fork() 在子进程中返回 0,在父进程中返回子进程的 PID。)要查看僵尸进程,您需要在父进程仍处于活动状态但尚未等待子进程时让子进程退出。如果你只是将代码的第 10 行从 `if (child_pid &gt; 0)` 更改为 `if (child_pid == 0)`,它将“修复”你的代码,当子进程运行时,你将能够看到僵尸进程。进程退出。 (3认同)
  • 只是为了详细说明一下。如果父进程先退出,则子进程现在是孤儿进程(其父进程已死亡),并且 init 进程将采用它(因此新的父进程的 pid 为 1)。init 进程注册了一个特殊的处理程序,以便在子进程死亡时收到通知,因此当子进程死亡时,它将等待它读取其状态代码,因此子进程不会成为僵尸进程。如果 init 进程不这样做(例如在 docker 内部运行时很常见),您的版本仍然会出现僵尸。 (3认同)

Aam*_*ari 6

Linux 中的僵尸进程或“失效进程”是指已经完成的进程,但由于父进程和子进程之间缺乏对应关系,其条目仍然保留在进程表中。通常,父进程通过 wait() 函数检查其子进程的状态。当子进程完成时,等待函数会通知父进程从内存中完全退出该进程。但是,如果父进程未能为其任何子进程调用等待函数,则子进程在系统中将作为死进程或僵尸进程保持活动状态。这些僵尸进程可能会在您的系统上大量积累并影响其性能。

下面是在我们的系统上创建 Zombie-Process 的 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;
}
Run Code Online (Sandbox Code Playgroud)

通过此代码创建的僵尸进程将运行 60 秒。您可以通过在 sleep() 函数中指定时间(以秒为单位)来增加持续时间。

编译这个程序

gcc zombie.c
Run Code Online (Sandbox Code Playgroud)

现在运行僵尸程序:

./a.out
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)