Linux中fork函式分析

2021-12-29 19:50:02 字數 2119 閱讀 8681

乙個程序,是包括**、資料和分配給程序的資源,fork()函式通過系統呼叫建立乙個與原來程序幾乎完全相同的程序,也就兩個程序可以完全做相同的事,但如果初始化引數或者傳入的變數不同,兩個程序也可以做不同的事

乙個程序呼叫fork()函式後,系統先給新的程序分配資源,例如儲存資料和**的空間。然後把原來的程序的所有值都複製到新的程序中,只有少數值與原來發的程序的值不同,相當於轉殖了乙個自己

fork呼叫的乙個奇妙之處就是它僅僅被呼叫一次,卻能能夠返回兩次,它可能有三種不同的返回值

1、在父程序中,fork返回新建立子程序的程序id

2、在子程序中,fork返回0

3、如果出現錯誤,fork返回-1

在fork函式執行完畢後,如果建立新程序成功,則出現兩個程序,乙個子程序、乙個主程序。在父程序中,fork返回新建立子程序的程序id。在子程序中,fork返回0,所以可以通過返回值來判斷當前是子程序還是父程序

fork出錯可能有兩種原因:

1)當前的程序數已經達到了系統規定的上限,這時errno的值被設定為eagain。

2)系統記憶體不足,這時errno的值被設定為enomem。

建立新程序成功後,系統**現兩個基本完全相同的程序,兩個程序執行沒有固定的先後順序,哪個程序先執行要看系統的程序排程策略

void main()

return;

}答案是14

注意這個題目輸出的時候有\n,重新整理了快取區,所以只能是14個,畫乙個二叉樹

。 第乙個不算,因為由他產生了其他兩個程序

i=0 。 。(2)

i=1 。 。 。 。(4)

i=2 。 。 。 。 。 。 。 。 (8)

#include

#include

#include

int main(void)

return 0;

}你可能覺得是6,但是實際上這個程式會輸出8個

我們首先需要知道fork()系統呼叫的特性

fork()系統呼叫是unix下以自身程序建立子程序的系統呼叫,一次呼叫,兩次返回,如果返回是0,則是子程序,如果返回0,則是父程序(返回值是子程序的pid),這是眾為周知的。

在fork()的呼叫處,整個父程序空間會複製到子程序中,包括指令,變數值,程式呼叫棧,環境變數,快取區,等等

所以,為什麼輸出8個,而不是6個,這是因為printf(「-」)語句有buffer,所以對於上述程式,printf(「-」)把「-」放在了快取中,並沒有真正的輸出,在fork的時候,快取被複製了子程序空間,所以,就多了2個,就成了8個。

我們知道,unix下的裝置有「塊裝置」和「字元裝置」的概念,所謂塊裝置,就是以一塊一塊的資料訪問的裝置,磁碟和記憶體是塊裝置,字元裝置是乙個訪問乙個字元裝置,字元裝置如鍵盤和串列埠。塊裝置一般都有快取,而字元裝置一般沒有快取

對於上面的問題,我們如果改為

printf("-\n");或

printf("-");

fflush(stdout);

那麼結果就是6個,因為程式遇到「\n」、eof、快取區滿、檔案描述符關閉、主動flush、程式退出,這幾種情況就會把資料刷出快取區

相同顏色代表同乙個程序

這樣,對於printf(「-」);這個語句,我們就可以很清楚的知道,哪個子程序複製了父程序標準輸出緩中區里的的內容,而導致了多次輸出了。(如下圖所示,就是我陰影並雙邊框了那兩個子程序)

虛擬位址空間,num位址的值相同,但是其實真實的實體地址卻不一樣。

如果安裝兩個程序各處在獨自的虛擬程序位址空間分析的話,這個題很容易會選擇num位址不相同,但是linux中資源分配都是虛擬機制,也就是說,他們還是共用乙個虛擬的位址,但是對映到物理記憶體就可能不一樣

Linux下程序建立Fork 函式分析

乙個程序包括 資料 程序控制塊 堆疊等資源。程序在執行時還有自身的狀態,這個自身的狀態不是指巨集觀上的就緒態 等待態,而是指程序在cpu上執行時,cpu內部各個暫存器的值,程序在切換的時候,這些狀態值是要儲存在堆疊當中的,目的是下次程序執行時能夠 無縫 連線。linux下,用於建立程序的函式是for...

linux中select 函式分析

select 的機制中提供一fd set的資料結構,實際上是一long型別的陣列,每乙個陣列元素都能與一開啟的檔案控制代碼 不管是socket控制代碼,還是其他 檔案或命名管道或裝置控制代碼 建立聯絡,建立聯絡的工作由程式設計師完成,當呼叫select 時,由核心根據io狀態修改fd set的內容,...

Linux中select函式分析

select在socket程式設計中還是比較重要的,可是對於初學socket的人來說都不太愛用select寫程式,他們只是習慣寫諸如connect accept recv或recvfrom這樣的阻塞程式 所謂阻塞方式block,顧名思義,就是程序或是執行緒執行到這些函式時必須等待某個事件的發生,如果...