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....