出于学习目的,我编写了一段代码来生成僵尸进程。这是代码:
#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。
答案 0 :(得分:0)
这里有两个问题。首先,您的\n
字符串末尾没有换行符(printf
)。由于stdout是行缓冲的,因此除非您打印换行符或显式刷新流,否则不会从输出缓冲区刷新输出。
所以添加一个换行符,它应该立即打印出来:
printf("the child process is %d\n", pid);
您没有看到孩子pid的主要原因与您使用ps
命令的方式有关。假设您从运行此代码的shell调用ps
,ps -l
仅显示运行该命令的会话中的进程。因此,不会出现从其他会话/ shell开始的进程。
如果您使用-e
选项(例如ps -el
或ps -ef
),则会显示系统中的完整进程列表。然后你应该能够看到僵尸进程。
答案 1 :(得分:0)
直到明天我才能访问MAC OS系统,但你的程序成功会在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 %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()。
}
}