1. 程式人生 > >Linux --------fork()函式:(一)

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去掉,會出現什麼樣的結果呢?