fork函數是Unix like系統都提供的有關操作系統進程處理的一個api。
fork函數可以獲得一個與父進程一模一樣的子進程,子進程獲得父進程的數據空間和堆棧的一個副本。換句話說,二者並不共享內存,而是獨立執行。
fork函數的最大特點是父進程的一次調用,可以有兩個返回,一個是父進程中返回子進程的id,一個是在子進程中返回0,還有一種情況是fork錯誤:原因一是進程超過最大值,原因二是內存不足。
一個進程調用fork()函數後,系統先給新的進程分配資源,例如存儲數據和代碼的空間。然後把原來的進程的所有值都
複製到新的新進程中,只有少數值與原來的進程的值不同。相當於克隆了一個自己。
我們來看一個例子:
- /*
- * fork_test.c
- * version 1
- * Created on: 2010-5-29
- * Author: wangth
- */
- #include <unistd.h>
- #include <stdio.h>
- #include <sys/types.h>
- int main ()
- {
- pid_t fpid; //fpid表示fork函數返回的值
- int count=0;
- fpid=fork();
- if (fpid < 0)
- printf("error in fork!");
- else if (fpid == 0) {
- printf("i am the child process, my process id is %d/n",getpid());
- printf("我是爹的兒子/n");//對某些人來說中文看着更直白。
- count++;
- }
- else {
- printf("i am the parent process, my process id is %d/n",getpid());
- printf("我是孩子他爹/n");
- count++;
- }
- printf("統計結果是: %d/n",count);
- return 0;
- }
運行結果是:
i am the child process, my process id is 5574
我是爹的兒子
統計結果是: 1
i am the parent process, my process id is 5573
我是孩子他爹
統計結果是: 1
注意在windows下無法使用fork函數,此程序需要在安裝有gcc編譯器的unixl ike環境下使用。
寫時複製
系統調用fork()創建進程的開始階段可能不需要按需調頁,這種技術提供了快速進程創建,且最小化新創建進程必須分配新的頁面的數量。
fork()是將子進程創建爲父進程的複製品。由於許多子進程在創建後通常馬上會執行系統調用exec(),所以父進程地址空間的複製可能沒有必要。使用一種稱爲寫時複製(copy-on-write)的技術。這種方法允許父進程與子進程寫時複製
系統調用fork()創建進程的開始階段可能不需要按需調頁,這種技術提供了快速進程創建,且最小化新創建進程必須分配新的頁面的數量。
fork()是將子進程創建爲父進程的複製品。由於許多子進程在創建後通常馬上會執行系統調用exec(),所以父進程地址空間的複製可能沒有必要。使用一種稱爲寫時複製(copy-on-write)的技術。這種方法允許父進程與子進程開始時共享同一頁面,這些頁面標記爲寫時複製頁,即如果任何一個進程需要對頁進行寫操作,那麼就創建一個共享頁的副本。子進程會修改其複製的頁,而非父進程的頁。進程修改的頁纔會被複制,所有非修改的頁可爲父進程和子進程所共享。注意只有可能修改的頁才需要標記寫時複製。開始時共享同一頁面,這些頁面標記爲寫時複製頁,即如果任何一個進程需要對頁進行寫操作,那麼就創建一個共享頁的副本。子進程會修改其複製的頁,而非父進程的頁。進程修改的頁纔會被複制,所有非修改的頁可爲父進程和子進程所共享。注意只有可能修改的頁才需要標記寫時複製。