作業系統 fork 函式的使用與底層原理

2021-08-11 19:18:08 字數 3193 閱讀 3850

在我第一次接觸到fork函式的時候,那個時候我在牛客網刷題然後呢碰到乙個關於fork()的函式的問題.總是沒有辦法理解那個printf()

為什麼輸出那

麼 多次.終於通過學習完程序的建立明白了fork()的時候到底發生了什麼事情. 下面我就來談一談我的一點小小的積累. 首

先我們來認識fork()的運用.

#includepid_t fork(void);

返回值:自程序中返回0,父程序返回程序id,出錯返回-1

fork()系統呼叫通過複製乙個現有程序來建立乙個全新的程序. 程序被存放在乙個叫做任務佇列的雙向迴圈鍊錶當中.鏈

表當中的每一項

都是型別為

task_struct成為程序描述符的結構.也就是我們寫過的

程序pcb

. 小知識:核心通過乙個位置的程序標識值或pid來標識每乙個程序.//最大值預設為32768,short int短整型的最大值. 他就是系統中允許

同時存在的進

程 最大的數目. 如果你覺得我在胡扯!!!  那麼! 你去你的linux下的proc目錄中尋找乙個 pid_max的檔案,並開啟它. 

這個時候你就懂了.

首先我們來看一段**,不過這裡會有一點奇怪的現象:

這段**的執行結果,大家如果像我當時不了解fork的時候,一定會以為輸出結果是兩個doing,然後2個printf裡面的內容. 因為

我們複製出來了兩個

一模一樣的程序,那麼他們就應該做同樣的事情. but!!! 我們看執行結果:

結果並非我們想的那樣,這個時候我們就需要知道fork出子程序之後,程式的執行細節.這裡我畫一張圖幫助我理解:

一般來說,在fork之後是父程序先執行還是子程序先執行是不確定的.這取決於核心所使用的排程演算法.如果要求父,子程序之間相

互同步.則要求某種

形式的程序間通訊. 好了我們繼續,當程序呼叫fork後,當控制轉移到核心中的fork**後,核心會做4件事情:

1.分配新的記憶體塊和核心資料結構給子程序

2.將父程序部分資料結構內容拷貝至子程序

3.新增子程序到系統程序列表當中

4.fork返回,開始排程器排程

第乙個問題,為什麼frok成功呼叫後返回兩個值?

由於在複製時複製了父程序的堆疊段,所以兩個程序都停留在fork函式中,等待返回.因為fork函式會返回兩次,一次是在父程序中返回,

另一次是在子程序中返回,這兩次的返回值不同. 

從fork函式開始以後的**父子共享,既父程序要執行這段**,子程序也要執行這段**.(子程序獲得父程序資料空間,堆和棧的副

本. 但是父子程序並不共享這些儲存空間部分. 父,子程序共享**段.)現在很多現實並不執行乙個父程序資料段,堆和棧的完全複製. 

而是採用

寫時拷貝技術(

不懂可以戳進去看一看).這些區域有父子程序共享,而且核心地他們的訪問許可權改為唯讀的.如果父子程序中任一

個試圖修改這些區域,則核心值為修改區域的那塊記憶體製作乙個副本, 也就是如果你不修改我們一起用,你修改了之後對於修改的那部分

內容我們分開各用個的.

fork()函式在底層中做了什麼?

linux平台通過clone()系統呼叫實現fork(). fork(),vfork()和clone()庫函式都根據各自需要的引數標誌去呼叫clone(),然後由clone()去

呼叫do_fork(). 再然後do_fork()完成了建立中的大部分工作,他定義在kernel/fork.c當中.該函式呼叫copy_process(). 然後重點來了,

我們看看這個copy_process函式到底做了那些事情?? 我畫一張圖幫我們理解:

vfork()的誕生是在fork()還沒有寫時拷貝的時候,因為那個時候建立乙個子程序的成本太大了,如果一下子建立好多了那麼程式的效率

一定會下

降. 然後就有人提出了vfork(). vfork的實現原理非常簡單,就是子程序,父程序完全公用乙個資源. 就是是有人修改了內容,

甚至main()函式退出了

也不會新開闢乙個空間. 這裡裡會有問題的,如果你的乙個子程序沒有使用exit()退出,那麼程式就會出現段錯誤. 

不相信可以去試一試~ 

為什麼會出現段錯誤? 

在函式棧上面,子程序執行結束了,main的函式棧被子程序釋放了,然後父程序在使用的時候,就訪問不到了,一旦vfork出子程序,

退出的時候需要

使用exit來結束.

vfork和fork之間的區別:

1.fork父子程序交替執行,vfork子程序執行,父程序阻塞,直到子程序結束.

2.fork實現了寫時拷貝. vfork直接讓父子程序公用資源然後無論如何也不會多開闢空間拷貝了,

3,vfork必須使用exit或者excl退出.

4.就算是fork使用了寫時拷貝,也沒有vfork效能高.

5.每個系統上的vfork都有問題,推薦不要使用.

作業系統實驗 fork函式理解

一 fork 函式的作用開闢出一塊記憶體空間 二 父程序與子程序被複製的程序是父程序,複製出來的程序叫子程序 三 注意事項 1.父程序的程序號一定小於子程序 因為肯定先有了父程序,才會有子程序 2.父程序呼叫fork 函式的返回值是子程序號 3.子程序呼叫fork 函式的返回值是0 4.由2,3,可...

fork 函式 fork 函式的使用

fork的意思是個叉子,在unix及其衍生版linux中,用於建立子程序,現在看一下fork函式的基本用法。include includeint main printf c b fflush stdout fork printf c c fflush stdout 上圖的輸出是什麼呢?答案是 bab...

作業系統 作業系統的設計與實現

系統設計的首要問題是定義目標和規範。從高層來說,系統設計取決於所選硬體和系統型別 批處理 分時 單使用者 多使用者 分布式 實時或通用。除了最高設計層外,需求可能很難說清,但需求可以分為兩類 使用者目標和系統目標。使用者要求系統具有一定的優良效能 系統應該易於學習和使用 可靠 安全和快速。研發人員為...