出于学习目的,我写了一段代码来生成僵尸进程。这是代码:
#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 调用ps
,ps -l
仅显示运行命令的会话中的进程。 因此,从其他会话/外壳启动的进程不会出现。
如果您使用-e
选项(即 ps -el
或ps -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系统中做同样的事情,并包括第三个创建僵尸进程的系统。