Linux --------fork()函式:(一)
fork()函式:
一:介紹
fork是在程序管理模組中的一個重要的函式。那麼怎樣來建立程序呢?
①:程式----- (執行)-----》程序 ./main
②:由程式建立程序 pid_t fork(void)
二:函式簡介
1.描述:一個現有程序可以呼叫fork函式建立一個新的程序。
2.標頭檔案:#include<unistd.h>
3.使用方法:pid_t n = fork()
4.返回值:fork()函式被呼叫一次返回兩次。
兩次返回值的區別是:子程序返回值是0,父程序返回子程序ID。
出錯返回0。
三:函式特點
1.為什麼要將子程序的ID返回給父程序?
因為一個程序的子程序可以有多個,並且沒有一個函式使一個程序可以獲得其所有子程序的ID。
2.fork使子程序得到的返回值為0的理由是?
一個程序只會有一個父程序,所以子程序總可以呼叫getppid以獲得其父程序的ID(程序ID為0 是由核心交換程序使用,所以 一個子程序的程序ID不可能為0)。
3.呼叫特點:父子程序繼續執行fork呼叫後的指令,子程序是父程序的副本。
例:子程序獲得父程序的資料空間,堆,棧的副本,注意這是子程序所擁有的副本,父子程序不共享這些儲存空間部分。
父子程序共享正文段。
4.寫時拷貝技術:父程序的資料段,棧,和堆有父子程序所共享,而且核心將他們的訪問許可權變為只讀的。if父子程序中的任意 一個試圖修改這些區域,則核心只為修改區域的那塊記憶體製作一個副本,通常為虛擬機器儲存器中的一個“頁”。
5.執行特點:
父程序創建出子程序後,兩個程序就是獨立的個體,各自執行互不干擾。
父子程序誰先執行不由fork來決定,由系統當前環境和程序排程演算法決定。
四:程式碼解析
五:程式碼聯絡
程式一:
int main() { pid_t n = fork(); assert(n != -1); if (n == 0) { printf("child fork is running:!\n"); } else { printf("father fork is running:!\n"); } exit(0); }
解析:
fork()函式的呼叫父程序返回子程序的ID,子程序返回0,所以父程序執行else,子程序執行if。
程式二:
int main()
{
if (fork() && fork())
{
printf("A \n");
}
else
{
printf("B \n");
}
exit(0);
}
解析:
考察fork()函式返回值 和 子程序保留父程序轉態,呼叫第一個fork()函式時,子程序1返回0,不執行邏輯與後面的判斷,直接執行else,輸出B。而父程序返回子程序1的ID,在判斷第二個fork()函式,其子程序2返回0,則執行lese輸出B,父程序返回子程序2的ID,執行if輸出A。
輸出兩個B一個A。
程式三:
int main()
{
int i = 0;
for (; i < 2; ++i)
{
if (fork() == 0)
printf("A \n");
else
printf("B \n");
}
exit(0);
}
解析:
由於這裡面涉及到,迴圈所以我們要搞清楚迴圈過程中的父子程序直接的關係!
這裡會輸出3個A和3個B.
程式四:問將程式3的兩個printf中的\n去掉,會出現什麼樣的結果呢?