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'在開始的兩個語句後,str1;str2[
1]='
w';
和str2
存放資料的位址是一樣的,而在修改內容後,
str1
的位址發生了變化,而
str2
的位址還是原來的,這就是c++中的cow技術的應用,不過vs2005似乎已經不支援cow。
寫時拷貝技術
cow技術初窺 在linux程式中,fork 會產生乙個和父程序完全相同的子程序,但子程序在此後多會exec系統呼叫,出於效率考慮,linux中引入了 寫時複製 技術,也就是只有程序空間的各段的內容要發生變化時,才會將父程序的內容複製乙份給子程序。那麼子程序的物理空間沒有 怎麼去取指令執行exec系...
寫時拷貝技術
寫時拷貝故名思意 是在寫的時候 即改變字串的時候 才會真正的開闢空間拷貝 深拷貝 如果只是對資料的讀時,只會對資料進行淺拷貝 寫時拷貝技術是通過 引用計數 實現的,在分配空間的時候多分配4個位元組,用來記錄有多少個指標指向塊空間,當有新的指標指向這塊空間時,引用計數加一,當要釋放這塊空間時,引用計數...
寫時拷貝技術
寫時拷貝的主要思想是在複製原來實體的時候,如果複製後的實體不需要進行改變,那麼實際上沒必要進行實體內容的拷貝,只需建立乙個引用指向原來的物理記憶體,直接應用原來的實體內容即可,只有當需要對複製後的實體進行修改的時候才進行內容的拷貝。寫時拷貝技術在很多方面都有應用,典型的有 c 中的寫時拷貝技術 li...