1.程序设计
利用fork函数产生一个子进程,当进程号小于0时报错,否则当进程号等于0时进入子进程输出它里面的内容“子进程已执行完毕并退出”,否则进入父进程执行,会让父进程休眠60s,保证子进程先于父进程执行结束,使子进程成为僵尸进程。同时父进程睡眠60s使能够有足够的时间来查看当前进程状态,以验证是否产生僵尸进程。
2.运行分析
如下图所示:由于僵尸进程的状态为Z,所以编译程序无错误之后利用命令ps aux | grep -w ‘Z’ (若只输入ps aux则输出显示所有进程)来输出显示当前系统所有进程状态行参数中含有Z的进程。可以看到,只由于所有的进程中只有进程4175的操作指令这一栏出现Z,所以输出了该进程,但可以看到该进程状态为S+(表示该进程正在睡眠),不是僵尸进程。
然后执行所写的程序产生一个僵尸进程,同时为了验证是否产生了,在父进程睡眠的同时打开另一个终端输出进程状态行中含有Z的进程,可以看到相比之前多出了一个僵尸进程(进程状态为Z+)。但是等父进程运行结束之后再次查看时候却找不到该僵尸进程了,起初以为是该僵尸进程随着父进程的退出而退出,但是查看资料后原来是父进程死掉之后其所有进程过继给init进程,init成为该僵尸进程的父进程。而init会周期性地去调用wait系统来清除它的僵尸孩子进程。因此父进程死掉后子僵尸进程跟着消失其实是因为init进程在为其收尸。
3.源码
//产生僵尸进程
#include "apue.h"
int main(void)
{
pid_t pid;
if ((pid = fork()) < 0)
err_sys("fork error");
else if (pid == 0)//子进程
{
printf("子进程已执行完毕并退出\n");
}
else //父进程
{
printf("父进程进入休眠状态\n");
sleep(60); //父进程休眠60s保证子进程先退出并成为僵尸进程
printf("父进程已醒来并退出\n");
}
return 0;
}