fork vfork 父進程和子進程的內存關係

  fork()會產生一個和父進程完全相同的子進程,但子進程在此後多會exec系統調用,出於效率考慮,linux中引入了“寫時複製“技術,也就是隻有進程空間的各段的內容要發生變化時,纔會將父進程的內容複製一份給子進程。於是起初我就感到奇怪,子進程的物理空間沒有代碼,怎麼去取指令執行exec系統調用呢?!原來在fork之後exec之前兩個進程用的是相同的物理空間(內存區),子進程的代碼段、數據段、堆棧都是指向父進程的物理空間,也就是說,兩者的虛擬空間不同,但其對應的物理空間是同一個。當父子進程中有更改相應段的行爲發生時,再爲子進程相應的段分配物理空間,如果不是因爲exec,內核會給子進程的數據段、堆棧段分配相應的物理空間(至此兩者有各自的進程空間,互不影響),而代碼段繼續共享父進程的物理空間(兩者的代碼完全相同)。而如果是因爲exec,由於兩者執行的代碼不同,子進程的代碼段也會分配單獨的物理空間。
       在網上看到還有個細節問題就是,fork之後內核會
通過將子進程放在隊列的前面,以讓子進程先執行,以免父進程執行導致寫時複製,而後子進程執行exec系統調用,因無意義的複製而造成效率的下降。

       詳細情況可以看看這位仁兄的文章:
十辨十析之辨一――fork()、寫時複製、vfork()

最近幾本關於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的一個主要特徵,也可以說是其高明處之一吧,其創建進程特別的高效,怎麼高效,通過以上的比較與分析,相信大家也能明白個五六了吧。

轉載至:http://igaozh.iteye.com/blog/1677969

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