fork()、寫時複製、vfork()

轉載:http://blogold.chinaunix.net/u2/66321/showart_725988.html

解釋得非常帥氣!

 

 

最近幾本關於 L 的書,想來通絡一下。也幹了近幾件瘋狂的事情,想想都要偷着自娛自樂一番,真是無聊到盡頭了,也就是另一番風景。有些你以前一直巴巴的信仰爲真的東西,偶樂改變一下,結果發現,原來不是那個理,換個道也沒什麼比以前差的,丫,這樣,也不錯。

打算寫十辨十析,羅羅一大堆,寫些什麼呢,想來想去,還是寫些基礎的東西吧, 希望這些基礎的東西對朋友們理解其它方面能有個幫助 。這個專題的思想: what ? why ? how ?  總之要從根基上講清楚,重點在原理上了。對了圖作的不精,請大家諒解。

這三個方法是大佬 L 用 於創建子進程的三種方法。其實理解它們,要有一個實現上的意識即:進程->虛擬地址空間->物理地址空間即真實的存儲。用戶進程能感知的是進程的虛擬地址 空間,而虛擬地址空間->物理地址空間則由底層的內核來幫你實現。一個進程在地址空間上的表現形式就是:正文段,數據段,堆,棧。嗯,主要就是這四個部 分,內核爲其分配相應的數據結構來表示它們,其看做是進程在地址空間的實體,也可以想象爲靈魂。隨後內核會爲這四部分分配相應的載體,即真正的物理存儲, 就像靈魂要附之於身體一樣,那麼,這些物理存儲就是進程的真正實體的,我們稱之爲身體。那麼這三個方法有什麼不同呢?

ok ,現在有一個父進程 P1 ,這是一個主體,那麼它是有靈魂也就身體的哦。現在在其虛擬地址空間(有相應的數據結構表示)上有:正文段,數據段,堆,棧這四個部分,相應的,內核要爲這四個部分分配各自的物理塊。即:正文段塊,數據段塊,堆塊,棧塊。至於如何分配,這是內核去做的事,在此不詳述。

1.       現在 P1 fork() 函數爲進程創建一個子進程 P2 ,內核:( 1 )複製 P1 的正文段,數據段,堆,棧這四個部分,注意是其內容相同。( 2 )爲這四個部分分配物理塊, P2 的:正文段-> PI 的正文段的物理塊,其實就是不爲 P2 分配正文段塊,讓 P2 的正文段指向 P1 的正文段塊,數據段-> P2 自己的數據段塊(爲其分配對應的塊),堆-> P2 自己的堆塊,棧-> P2 自己的棧塊。如下圖所示:同左到右大的方向箭頭表示複製內容。


圖1

 

2.       寫時複製技術:內核只爲新生成的子進程創建虛擬空間結構,它們來複制於父進程的虛擬究竟結構,但是不爲這些段分配物理內存,它們共享父進程的物理空間,當父子進程中有更改相應段的行爲發生時,再爲子進程相應的段分配物理空間。


圖2

3.       vfork() :這個做法更加火爆,內核連子進程的虛擬地址空間結構也不創建了,直接共享了父進程的虛擬空間,當然了,這種做法就順水推舟的共享了父進程的物理空間。


圖3

通 過以上的分析,相信大家對進程有個深入的認識,它是怎麼一層層體現出自己來的,進程是一個主體,那麼它就有靈魂與身體,系統必須爲實現它創建相應的實體, 靈魂實體與物理實體。這兩者在系統中都有相應的數據結構表示,物理實體更是體現了它的物理意義。呵呵,說了這麼多,其實系統之所以提供這三個方法,也都是 從實現效率上來考慮的,一般 fork 後要 exec ,所以很多父進程的數據對於子進程來說都是不需要的,後兩種方法就是大佬 L 區別於 Unix 的一個主要特徵,也可以說是其高明處之一吧,其創建進程特別的高效,怎麼高效,通過以上的比較與分析,相信大家也能明白個五六了吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章