fork()函數測試

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章