標籤:
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/20/2601655.html
源於網上資料
COW技術初窺:
在Linux程式中,fork()會產生一個和父進程完全相同的子進程,但子進程在此後多會exec系統調用,出於效率考慮,linux中引入了“寫時複製“技術,也就是只有進程空間的各段的內容要發生變化時,才會將父進程的內容複寫一份給子進程。
那麼子進程的物理空間沒有代碼,怎麼去取指令執行exec系統調用呢?
在fork之後exec之前兩個進程用的是相同的物理空間(記憶體區),子進程的程式碼片段、資料區段、堆棧都是指向父進程的物理空間,也就是說,兩者的虛擬空間不同,但其對應的物理空間是同一個。當父子進程中有更改相應段的行為發生時,再為子進程相應的段分配物理空間,如果不是因為exec,核心會給子進程的資料區段、堆棧段分配相應的物理空間(至此兩者有各自的進程空間,互不影響),而程式碼片段繼續共用父進程的物理空間(兩者的代碼完全相同)。而如果是因為exec,由於兩者執行的代碼不同,子進程的程式碼片段也會分配單獨的物理空間。
在網上看到還有個細節問題就是,fork之後核心會通過將子進程放在隊列的前面,以讓子進程先執行,以免父進程執行導致寫時複製,而後子進程執行exec系統調用,因無意義的複製而造成效率的下降。
COW詳述:
現在有一個父進程P1,這是一個主體,那麼它是有靈魂也就身體的。現在在其虛擬位址空間(有相應的資料結構表示)上有:本文段,資料區段,堆,棧這四個部分,相應的,核心要為這四個部分分配各自的物理塊。即:本文段塊,資料區段塊,堆塊,棧塊。至於如何分配,這是核心去做的事,在此不詳述。
1. 現在P1用fork()函數為進程建立一個子進程P2,
核心:
(1)複製P1的本文段,資料區段,堆,棧這四個部分,注意是其內容相同。
(2)為這四個部分分配物理塊,P2的:本文段->PI的本文段的物理塊,其實就是不為P2分配本文段塊,讓P2的本文段指向P1的本文段塊,資料區段->P2自己的資料區段塊(為其分配對應的塊),堆->P2自己的堆塊,棧->P2自己的棧塊。如所示:同左到右大的方向箭頭表示複製內容。
2. 寫時複製技術:核心只為新產生的子進程建立虛擬空間結構,它們來複製於父進程的虛擬究竟結構,但是不為這些段分配實體記憶體,它們共用父進程的物理空間,當父子進程中有更改相應段的行為發生時,再為子進程相應的段分配物理空間。
3. vfork():這個做法更加火爆,核心連子進程的虛擬位址空間結構也不建立了,直接共用了父進程的虛擬空間,當然了,這種做法就順水推舟的共用了父進程的物理空間
通過以上的分析,相信大家對進程有個深入的認識,它是怎麼一層層體現出自己來的,進程是一個主體,那麼它就有靈魂與身體,系統必須為實現它建立相應的實體, 靈魂實體與物理實體。這兩者在系統中都有相應的資料結構表示,物理實體更是體現了它的物理意義。以下援引LKD
傳統的fork()系統調用直接把所有的資源複製給新建立的進程。這種實現過於簡單並且效率低下,因為它拷貝的資料也許並不共用,更糟的情況是,如果新進程打算立即執行一個新的映像,那麼所有的拷貝都將前功盡棄。Linux的fork()使用寫時拷貝(copy-on-write)頁實現。寫時拷貝是一種可以延遲甚至免除拷貝資料的技術。核心此時並不複製整個進程地址空間,而是讓父進程和子進程共用同一個拷貝。只有在需要寫入的時候,資料才會被複製,從而使各個進程擁有各自的拷貝。也就是說,資源的複製只有在需要寫入的時候才進行,在此之前,只是以唯讀方式共用。這種技術使地址空間上的頁的拷貝被延遲到實際發生寫入的時候。在頁根本不會被寫入的情況下—舉例來說,fork()後立即調用exec()—它們就無需複製了。fork()的實際開銷就是複製父進程的頁表以及給子進程建立惟一的進程描述符。在一般情況下,進程建立後都會馬上運行一個可執行檔檔案,這種最佳化可以避免拷貝大量根本就不會被使用的資料(地址空間裡常常包含數十兆的資料)。由於Unix強調進程快速執行的能力,所以這個最佳化是很重要的。這裡補充一點:Linux COW與exec沒有必然聯絡
PS:實際上COW技術不僅僅在Linux進程上有應用,其他例如C++的String在有的IDE環境下也支援COW技術,即例如:
string str1 = "hello world";string str2 = str1;
之後執行代碼:
str1[1]=‘q‘;str2[1]=‘w‘;
在開始的兩個語句後,str1和str2存放資料的地址是一樣的,而在修改內容後,str1的地址發生了變化,而str2的地址還是原來的,這就是C++中的COW技術的應用,不過VS2005似乎已經不支援COW。
【轉】Linux寫時拷貝技術(copy-on-write)