C语言 调用 exit() 但不成为僵尸的子进程



出于学习目的,我写了一段代码来生成僵尸进程。这是代码:

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
pid_t pid;
int main() {
  pid = fork();
  if (pid == 0) {
    exit(0);
  } else {
   printf("the child process is %d", pid);
    sleep(20);
  }
}

在我的假设中,上面的代码应该以这样的方式运行:子进程接收 0 pid,状态代码为 0 exit;父进程接收子进程的pid并将其打印出来并进入睡眠状态 20 秒。因为父进程在子进程exit时不会调用wait,所以子进程应该是僵尸状态大约 20 秒。

但是,当我运行代码时,它会等待大约 20 秒并打印出子进程的 pid。在 20 秒内,子进程不会在ps -l中显示为僵尸进程。

有人可以告诉我,我对代码的理解与其实际行为之间有什么不同吗?

附言我正在使用Mac OS Sierra。

这里有两个问题。 首先是printf字符串末尾没有换行符(n(。 由于 stdout 是行缓冲的,因此不会从输出缓冲区刷新输出,除非您打印换行符或显式刷新流。

因此,添加一个换行符,它应该立即打印:

printf("the child process is %dn", pid);

您没有看到子 pid 的主要原因与您如何使用 ps 命令有关。 假设您从运行此代码的 shell 不同的 shell 调用psps -l仅显示运行命令的会话中的进程。 因此,从其他会话/外壳启动的进程不会出现。

如果您使用-e选项(即 ps -elps -ef (,这将显示系统中进程的完整列表。 然后你应该能够看到僵尸过程。

直到明天我才能访问 MAC 操作系统,但您的程序成功地在 Linux 系统中创建了一个僵尸进程。 我已经修改了您的示例代码以在父进程退出时添加一条消息,并且已经注释的 n char 正确结束该行并在调用时产生输出printf()

僵尸

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
pid_t pid;
int main() {
  pid = fork();
  if (pid == 0) {
    exit(0);
  } else {
    printf("the child process is %dn", pid);
    sleep(20);
    printf("exit();n");
  }
}

Linux 中的输出是:

$ zombie &
[1] 5781
the child process is 5786
$ ps
  PID TTY          TIME CMD
 2569 pts/0    00:00:00 bash
 5781 pts/0    00:00:00 zombie
 5786 pts/0    00:00:00 zombie <defunct>   <-- this is the zombie.
 5795 pts/0    00:00:00 ps
$ exit();  <-- zombie program finishing.

在FreeBSD(和MAC OS非常相似(上,事情是这样的:

$ zombie &
[1] 7326
the child process is 7329
$ ps
  PID TT  STAT       TIME COMMAND
 7281  0  Ss      0:00,18 -bash (bash)
 7326  0  S       0:00,02 zombie
 7329  0  Z       0:00,00 <defunct>  <-- this is the zombie.
 7335  0  R+      0:00,01 ps
$ exit();  <-- zombie program finishing.

明天我将能够在Mac OS X系统中做同样的事情,并包括第三个创建僵尸进程的系统。

最新更新