fork函數

 在Unix/Linux中用fork函數建立一個新的進程。進程是由當前已有進程調用fork函數建立,分叉的進程叫子進程,建立者叫父進程。該函數的特色是調用一次,返回兩次,一次是在父進程,一次是在子進程。兩次返回的區別是子進程的返回值爲0,父進程的返回值是新子進程的ID。子進程與父進程繼續併發運行。若是父進程繼續建立更多的子進程,子進程之間是兄弟關係,一樣子進程也能夠建立本身的子進程,這樣能夠創建起定義關係的進程之間的一種層次關係。html

  程序包含位於內存的多個組成部分,執行程序的過程將根據須要來訪問這些內容,包括文本段(text segment)、數據段(data segments)、棧(stack)和堆(heap)。文本段中存放CPU所執行的命令,數據段存放進程操做的全部數據變量,棧存放自動變量和函數數據,堆存放動態內存分配狀況數據。當進程被建立時,子進程收到父進程的數據副本,包括數據空間、堆、棧和進程描述符。linux

程序1:建立一個子進程,子進程對繼承的數據進行修改,而後分別輸出父子進程的信息。程序以下:面試

View Code

fork函數執行後程序結構圖以下:服務器

子進程與父進程並行執行,所以在父進程中sleep(10),讓子進程先執行,而後再執行父進程。併發

程序執行結果以下所示:函數

如何建立多個子進程呢?在開發併發服務器時,用到的進程池模型須要先建立指定書目的子進程。舉個例子,假如咱們如今須要建立2個子進程,很容易想到的是調用一個循環,執行fork函數2次便可。嘗試一下是否可行呢?代碼以下:測試

View Code

程序執行結果以下:spa

從結果來看,子進程的數目不是2而是3,這是爲何呢?先簡單的分析一下:從結果看出父進程ID爲10669,子進程的ID分別爲:10670、1067一、10672。3d

父子進程之間的關係以下:code

ID爲10670的子進程也調用fork函數,建立了一個進程。由於fork函數建立的進程是父進程的一份拷貝,保存了當前的數據空間、堆、棧及共享代碼區域。正確的方式應該是在子進程中跳出,中止繼續fork。改進的代碼以下:

View Code

程序執行結果以下:

 從結果能夠看出這父進程(ID爲10789)建立了兩個子進程(ID分別爲:10790、10791)。

現有有這樣一個面試題,程序以下:

複製代碼
 1 #include <stdio.h>
 2 #include <unistd.h>
 3 #include <stdlib.h>
 4 #include <sys/types.h>
 5 
 6 int main()
 7 {
 8     pid_t   pid1;
 9     pid_t   pid2;
10 
11     pid1 = fork();
12     pid2 = fork();
13 
14     printf("pid1=%d,pid2=%d\n",pid1,pid2);
15     exit(0);
16 }
複製代碼

要求以下:
 已知從這個程序執行到這個程序的全部進程結束這個時間段內,沒有其它新進程執行。
 一、請說出執行這個程序後,將一共運行幾個進程。
 二、若是其中一個進程的輸出結果是「pid1:1001, pid2:1002」,寫出其餘進程的輸出結果(不考慮進程執行順序)。

  這個題目考查fork函數的理解。fork的做用是複製一個與當前進程同樣的進程。新進程的全部數據(變量、環境變量、程序計數器等)數值都和原進程一致,可是是一個全新的進程,並做爲原進程的子進程,父子進程並行的執行剩下的部分。

程序的執行過程以下:

(1)程序開始執行時候系統分配一個進程進行執行,稱該進程爲主進程P,進程ID題目未給,

(2)主進程執行到第一個fork函數的時候,建立一個新的子進程P1,有題目可知進程ID爲1001,fork函數有兩個返回值,返回pid=0表明子進程P1,pid1>0表明父進程P。

(3)如今有兩個進程P和P1,分別執行剩下部分,

(4)P進程(父進程,因此pid1=1001)調用fork建立子進程P2,返回兩個值中pid2=1002表示P2的進程ID返回給父進程P,pid2=0子進程P2自己,因此輸出pid1=1001,         pid2=1002和pid1=1001,pid2=0。

(5)P1進程(子進程,因此pid1=0)調用fork建立子進程P3,進程ID類推爲1003,返回兩個值中pid2=1003表示P3的進程ID返回給父進程P1,pid2=0標識進程P3自己。因此輸出pid1=0,pid2=1003和pid1=0,pid2=0。

(6)執行整個結束。

根據以上分析可知答案:

一、一共執行了四個進程。(P0, P1, P2, P3)

二、另外幾個進程的輸出分別爲:

 pid1:1001, pid2:0

 pid1:0, pid2:1003

 pid1:0, pid2:0

上機測試以下:

測試結果以下:

測試結果雖然不是1001,可是能夠看出理論分析過程是正確的。

題目來自:http://www.cnblogs.com/leoo2sk/archive/2009/12/11/talk-about-fork-in-linux.html

相關文章
相關標籤/搜索