copy-on-write解決的問題
早期unix系統建立程序的方式存在缺陷:當發出fork()系統呼叫時,核心原樣複製父程序的整個位址空間並把複製的那乙份分配給子程序。這種行為是非常耗時的,因為它需要:
- 為子程序的頁表分配頁幀
- 為子程序的頁分配頁幀
- 初始化子程序的頁表
- 把父程序的頁複製到子程序相應的頁中
這種建立位址空間的方法涉及許多記憶體訪問,消耗許多cpu週期,並且完全破壞了快取記憶體中的內容。並且由於許多子程序通過exec()函式裝入乙個新的程式開始執行,這樣造成之前繼承位址空間的操作變成白費。
copy-on-write寫時複製
建立子程序時,並不複製整個父程序的位址空間,而是讓子程序和父程序共享同乙個位址空間,不需要寫的時候以唯讀方式共享
只,在需要寫入的時候才進行位址空間的複製。
寫時複製是常用的優化手段,記憶體管理器利用它可以節約記憶體。寫時複製是「延遲計算(lazy evaluation)」的乙個例子,可以歸類於資源延遲分配。只有在真正需要使用資源時才占用資源, 寫時複製通常能減少資源的占用。延遲計算使得只有當絕對需要時才執行乙個昂貴的操作。
copy-on-write機制
父程序和子程序共享頁幀而不是複製頁幀。然而,只要頁幀被共享,它們就不能被修改,即頁幀被保護。無論父程序還是子程序何時試圖寫乙個共享的頁幀,就產生乙個異常,這時核心才把這個頁複製到乙個新的頁幀中並標記為可寫。原來的頁幀仍然是寫保護的:當其他程序試圖寫入時,核心檢查寫程序是否是這個頁幀的唯一屬主,如果是,就把這個頁幀標記為對這個程序是可寫的。
當程序為乙個包含讀/寫頁面的記憶體區物件映**乙份寫時檢視,而並非在對映該檢視時建立乙份程序私有的拷貝(hewlett packard openvms作業系統就是這樣做的)時,記憶體管理器將頁面拷貝的動作推遲到頁面被寫入資料的時候。
所有現代的unix系統也都使用了這項技術。如:2個程序正在共享3個頁面,每個頁面都被標記為寫時複製,但是這2個程序都不打算修改頁面上的任何資料。如果這2個程序中任何乙個執行緒對乙個頁面執行了寫操作,則產生乙個記憶體管理錯誤。記憶體管理器看到,此寫操作作用在乙個寫時複製的頁面上,所以,它不是將此錯誤報告為訪問違例,而是在物理記憶體中分配乙個新的讀/寫頁面,並且把原始頁面中的內容拷貝到新的頁面中。同時也更新一下該程序中對應的頁面對映資訊,使它指向新的頁面位置,然後解除異常,從而使得剛才產生錯誤的那條指令得以重新執行。這一次,寫操作成功了。但是,新拷貝的頁面現在對於執行寫操作的那個程序來說是私有的,對於其它仍然在共享這一寫時複製頁面的程序來說,它是不可見的。每個往共享頁面中寫入資料的程序都將獲得它自己的私有拷貝。
copy-on-write的應用
php核心中的寫時複製
Copy On Write 寫時複製
維基百科 寫入時複製 copy on write 是乙個被使用在程式設計領域的最佳化策略。其基礎的觀念是,如果有多個呼叫者 callers 同時要求相同資源,他們會共同取得相同的指標指向相同的資源,直到某個呼叫者 caller 嘗試修改資源時,系統才會真正複製乙個副本 private copy 給該...
寫時複製Copy On Write
copy on write簡稱cow,不是奶牛,好處就是能保證資料的完整性,掉電的話容易恢復。在執行複製和賦值的時候,不會真正的copy,只有真正對內容進行修改時,才會進行複製,複製完之後再去修改 懶複製 copy on write一定使用了 引用計數 必然有乙個變數類似於refcnt 當第乙個st...
關於 copy on write 寫時複製
先舉個小例子,在我們學習c 的時候,我不相信老師沒跟你提過什麼是字串string淺拷貝深拷貝的問題,就是 string a i am a programer string b a 這是所謂的淺拷貝,當然我們不是在討論淺拷貝的問題,我只是讓大家知道b只是字串 i am a programer 的乙個引...