請你回答一下fork和vfork的區別

2021-09-24 18:00:49 字數 2582 閱讀 8031

fork:建立乙個和當前程序映像一樣的程序可以通過fork( )系統呼叫:

#include #include pid_t fork(void);

成功呼叫fork( )會建立乙個新的程序,它幾乎與呼叫fork( )的程序一模一樣,

這兩個程序都會繼續執行。在子程序中,成功的fork( )呼叫會返回0。在父

程序中fork( )返回子程序的pid。如果出現錯誤,fork( )返回乙個負值。

最常見的fork( )用法是建立乙個新的程序,然後使用exec( )載入二進位制映像

,替換當前程序的映像。這種情況下,派生(fork)了新的程序,而這個子

程序會執行乙個新的二進位制可執行檔案的映像。這種「派生加執行」的方式是

很常見的。

在早期的unix系統中,建立程序比較原始。當呼叫fork時,核心會把所有的

內部資料結構複製乙份,複製程序的頁表項,然後把父程序的位址空間中的

內容逐頁的複製到子程序的位址空間中。但從核心角度來說,逐頁的複製方

式是十分耗時的。現代的unix系統採取了更多的優化,例如linux,採用了

寫時複製的方法,而不是對父程序空間程序整體複製。

vfork的基礎知識:

在實現寫時複製之前,unix的設計者們就一直很關注在fork後立刻執行exec所造成的位址

空間的浪費。bsd的開發者們在3.0的bsd系統中引入了vfork( )系統呼叫。

#include #include pid_t vfork(void);

除了子程序必須要立刻執行一次對exec的系統呼叫,或者呼叫_exit( )退出,對vfork( )的成

功呼叫所產生的結果和fork( )是一樣的。vfork( )會掛起父程序直到子程序終止或者執行了一

個新的可執行檔案的映像。通過這樣的方式,vfork( )避免了位址空間的按頁複製。在這個

複製內部的核心資料結構。因此,子程序也就不能修改位址空間中的任何記憶體。

vfork( )是乙個歷史遺留產物,linux本不應該實現它。需要注意的是,即使增加了寫時複製,

vfork( )也要比fork( )快,因為它沒有進行頁表項的複製。然而,寫時複製的出現減少了對於

替換fork( )爭論。實際上,直到2.2.0核心,vfork( )只是乙個封裝過的fork( )。因為對vfork( )

的需求要小於fork( ),所以vfork( )的這種實現方式是可行的。

補充知識點:寫時複製

linux採用了寫時複製的方法,以減少fork時對父程序空間程序整體複製帶來的開銷。

寫時複製是一種採取了惰性優化方法來避免複製時的系統開銷。它的前提很簡單:

如果有多個程序要讀取它們自己的那部門資源的副本,那麼複製是不必要的。每

個程序只要儲存乙個指向這個資源的指標就可以了。只要沒有程序要去修改自己

的「副本」,就存在著這樣的幻覺:每個程序好像獨佔那個資源。從而就避免了復

制帶來的負擔。如果乙個程序要修改自己的那份資源「副本」,那麼就會複製那份

資源,並把複製的那份提供給程序。不過其中的複製對程序來說是透明的。這個

程序就可以修改複製後的資源了,同時其他的程序仍然共享那份沒有修改過的資

源。所以這就是名稱的由來:在寫入時進行複製。

寫時複製的主要好處在於:如果程序從來就不需要修改資源,則不需要進行複製。

惰性演算法的好處就在於它們盡量推遲代價高昂的操作,直到必要的時刻才會去執行。

在使用虛擬記憶體的情況下,寫時複製(copy-on-write)是以頁為基礎進行的。所以

,只要程序不修改它全部的位址空間,那麼就不必複製整個位址空間。在fork( )呼叫

結束後,父程序和子程序都相信它們有乙個自己的位址空間,但實際上它們共享父進

程的原始頁,接下來這些頁又可以被其他的父程序或子程序共享。

寫時複製在核心中的實現非常簡單。與核心頁相關的資料結構可以被標記為唯讀和寫

時複製。如果有程序試圖修改乙個頁,就會產生乙個缺頁中斷。核心處理缺頁中斷的

方式就是對該頁進行一次透明複製。這時會清除頁面的cow屬性,表示著它不再被共

享。現代的計算機系統結構中都在記憶體管理單元(mmu)提供了硬體級別的寫時複製支援

,所以實現是很容易的。

在呼叫fork( )時,寫時複製是有很大優勢的。因為大量的fork之後都會跟著執行exec,

子程序立刻執行乙個新的二進位制可執行檔案的映像,它先前的位址空間就會被交換出

去。寫時複製可以對這種情況進行優化。

fork和vfork的區別:

1. fork( )的子程序拷貝父程序的資料段和**段;vfork( )的子程序與父程序共享資料段

2. fork( )的父子程序的執行次序不確定;vfork( )保證子程序先執行,在呼叫exec或exit

3. 之前與父程序資料是共享的,在它呼叫exec或exit之後父程序才可能被排程執行。

4. vfork( )保證子程序先執行,在它呼叫exec或exit之後父程序才可能被排程執行。如果

5. 在呼叫這兩個函式之前子程序依賴於父程序的進一步動作,則會導致死鎖。

4.當需要改變共享資料段中變數的值,則拷貝父程序。

有益的,回答一下 GO

1 下列程式定義了乙個calc add類,請寫出程式的執行結果。public class calc add system.out.print sum sum 執行結果為 2 請寫出程式的執行結果。class person public int getweight public int getheig...

請你來說一下共享記憶體相關api

linux允許不同程序訪問同乙個邏輯記憶體,提供了一組api,標頭檔案在sys shm.h中。1 新建共享記憶體shmget int shmget key t key,size t size,int shm key 共享記憶體鍵值,可以理解為共享記憶體的唯一性標記。size 共享記憶體大小 shmf...

chrome弱網 請你進行一下弱網模擬

使用chrome的webview除錯工具,缺點是只適用於web頁面的弱網模擬。方法二 chrome的webview除錯工具弱網模擬 使用chrome的webview除錯工具,缺點是只適用於web頁面的弱網模擬。具體步驟 1 應用開啟webview除錯功能,具體如下 if build.version....