调用退出的子进程()但不会成为僵尸

时间:2017-05-17 03:35:32

标签: c process operating-system

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

#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秒。因为父进程在子进程wait时没有调用exit,所以子进程应该是僵尸大约20秒。

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

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

P.S。我正在使用Mac OS Sierra。

3 个答案:

答案 0 :(得分:0)

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

所以添加一个换行符,它应该立即打印出来:

printf("the child process is %d\n", pid);

您没有看到孩子pid的主要原因与您使用ps命令的方式有关。假设您从运行此代码的shell调用psps -l仅显示运行该命令的会话中的进程。因此,不会出现从其他会话/ shell开始的进程。

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

答案 1 :(得分:0)

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

zombie.c

#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\n", 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系统中做同样的事情,并包括一个创建僵尸进程的第三个系统。

答案 2 :(得分:-1)

你是什么意思“子进程不会出现在ps -l中作为僵尸进程”?你看到的状态是什么?或许你的意思是说你没有看到孩子?为了清楚起见,您可以通过运行“ps 1234”(或者您获得的任何pid)来检查该过程。

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

pid_t pid;

为什么这是一个全球性的?

int main() {

应该是int main(void)。

  pid = fork();
  if (pid == 0) {
    exit(0);

应该_Exit以避免调用“退出”处理程序。在这个玩具例子中没关系,但没有理由养成错误的习惯。

  } else {
   printf("the child process is %d", pid);
    sleep(20);

你可以改为暂停()或getchar()。

  }
}
相关问题