#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
pid_t pid;
if( (pid = fork()) < 0)
{
printf("error!\n");
return -1;
}
else if( pid == 0 )
{
int n = 5;
while( n-- )
{
sleep(1);
printf("this is child\n");
}
printf("child is over!\n");
exit(0);
}
else
{
while(1)
{
sleep(1);
printf("this is parent!\n");
}
}
return 0;
}
编译并运行此程序:
调用ps aux | grep a.out:
这是前五秒打印的结果:
linux@ubuntu:~/16071$ ps aux | grep a.out
linux 3411 0.0 0.0 1988 280 pts/3 S+ 16:42 0:00 ./a.out
linux 3412 0.0 0.0 1988 56 pts/3 S+ 16:42 0:00 ./a.out
linux 3414 0.0 0.1 4368 832 pts/4 S+ 16:42 0:00 grep --color=auto a.out
这是五秒后打印的结果:
linux@ubuntu:~/16071$ ps aux | grep a.out
linux 3411 0.0 0.0 1988 280 pts/3 S+ 16:42 0:00 ./a.out
linux 3412 0.0 0.0 0 0 pts/3 Z+ 16:42 0:00 [a.out] <defunct>
linux 3421 0.0 0.1 4368 832 pts/4 S+ 16:42 0:00 grep --color=auto a.out
这是程序执行的结果:
linux@ubuntu:~/16071$ ./a.out
this is parent!
this is child
this is parent!
this is child
this is parent!
this is child
this is child
this is parent!
this is child
child is over!
this is parent!
this is parent!
this is parent!
this is parent!
如何避免僵尸程序?
百科中的解释:
⒈父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。
⒉ 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后, 父进程会收到该信号,可以在handler中调用wait回收。
⒊ 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD,SIG_IGN) 通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收, 并不再给父进程发送信号。
⒋ 还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一 个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收 还要自己做。
个人认为方法2、3还是不错的。