1.脚本如下:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
if ( fork() != 0 )
{
printf("I am parent,PID=%d\n",getpid()); //输出父进程的id,父进程运行50s
sleep(50);
}
else
{
if ( fork() != 0)
{
sleep(10);
printf("I am child,PID=%d\n",getpid()); //输出子进程的id,子进程运行10s
}
else
{
sleep(30);
printf("I am sun-child,PID=%d\n",getpid()); //输出孙子进程的id,孙子进程运行30s
}
}
return 0;
}
执行结果:
[root@demo Desktop]# ./fork1
I am parent,PID=29195 ---->执行时立即输出
I am child,PID=29196 ---->10s后子进程输出
I am sun-child,PID=29197---->30后孙子进程输出
1.执行./fork1后的输出,I am parent,PID=29195,查看进程pid如下,
有3个fork1进程,分别是父进程29195,子进程29196,孙子进程29197
[root@demo ~]# ps -al
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 0 29195 5701 0 77 0 - 379 - pts/4 00:00:00 fork1
1 S 0 29196 29195 0 78 0 - 378 - pts/4 00:00:00 fork1
1 S 0 29197 29196 0 78 0 - 378 - pts/4 00:00:00 fork1
4 R 0 29198 16372 0 78 0 - 1051 - pts/1 00:00:00 ps
4 S 0 29507 21039 0 77 0 - 1222 wait pts/2 00:00:00 su
4 S 508 29508 29507 0 75 0 - 1132 - pts/2 00:00:00 bash
2.10s后,子进程结束,并输出I am child,PID=29196
由于父进程29195还没结束,也没有调用waitpid函数来清除它的子进程,所以子
进程29196显示为zombie进程,
此时孙子进程29197,他的父进程29196已经是zombie进程,所以由init 1收纳它并
成为它新的父进程,这也是fork()两次来避免zombie进程的原理,让子进程fork后
立即退出,交由孙子进程执行任务,孙子进程的父进程将变成变成init 1,孙子进
程运行结束后init 1会清除孙子进程.
[root@demo ~]# ps -al
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 0 29195 5701 0 77 0 - 379 - pts/4 00:00:00 fork1
1 Z 0 29196 29195 0 78 0 - 0 exit pts/4 00:00:00 fork <defunct>
1 S 0 29197 1 0 78 0 - 378 - pts/4 00:00:00 fork1
4 R 0 29217 16372 0 77 0 - 1050 - pts/1 00:00:00 ps
4 S 0 29507 21039 0 77 0 - 1222 wait pts/2 00:00:00 su
4 S 508 29508 29507 0 75 0 - 1132 - pts/2 00:00:00 bash
3.30s后孙子进程29197结束,父进程还需要再运行20s
[root@demo ~]# ps -al
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 0 29195 5701 0 77 0 - 379 - pts/4 00:00:00 fork1
1 Z 0 29196 29195 0 78 0 - 0 exit pts/4 00:00:00 fork <defunct>
4 R 0 29267 16372 0 77 0 - 1051 - pts/1 00:00:00 ps
4 S 0 29507 21039 0 77 0 - 1222 wait pts/2 00:00:00 su
4 S 508 29508 29507 0 75 0 - 1132 - pts/2 00:00:00 bash
4.孙子进程结束后的20s,也就是从执行脚本开始50s后父进程29195结束,
子进程29196也结束
[root@demo ~]# ps -al
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 R 0 29304 16372 0 77 0 - 1042 - pts/1 00:00:00 ps
4 S 0 29507 21039 0 77 0 - 1222 wait pts/2 00:00:00 su
4 S 508 29508 29507 0 75 0 - 1132 - pts/2 00:00:00 bash