寫時拷貝技術 COW

2021-09-24 14:17:08 字數 1875 閱讀 3187

寫時拷貝技術實際上是一種拖延戰術,是為了提高效率而產生的技術,這怎麼提高效率呢?實際上就是在需要開闢空間時,假裝開了空間,實際上用的還是原來的空間,減少開闢空間的時間,等到真正要使用新空間的時候才去真正開闢空間。

舉乙個例子理解寫時拷貝技術:我們小時候經常會遇到這種情況:家裡面有哥哥姐姐的,大人們經常會讓我們穿哥哥姐姐穿剩的衣服,這樣看起來我們就有了新衣服,但實際上我們穿的還是哥哥姐姐的舊衣服,等到我們真的長大了,才會給我們買屬於自己的新衣服,這樣節省了給我們買衣服的時間和財力。從而節省了很多資源(提高效率)。等我們真的需要時才不得不買新衣服(拖延戰術)。

寫時拷貝技術實際上是運用了乙個 「引用計數」 的概念來實現的。在開闢的空間中多維護四個位元組來儲存引用計數。

有兩種方法:

①:多開闢四個位元組(pcount)的空間,用來記錄有多少個指標指向這片空間。

②:在開闢空間的頭部預留四個位元組的空間來記錄有多少個指標指向這片空間。

當我們多開闢乙份空間時,讓引用計數+1,如果有釋放空間,那就讓計數-1,但是此時不是真正的釋放,是假釋放,等到引用計數變為 0 時,才會真正的釋放空間。如果有修改或寫的操作,那麼也讓原空間的引用計數-1,並且真正開闢新的空間。

linux 下的 fork() 就是用的寫時拷貝技術,引用計數不光在 string 這裡用到,還有智慧型指標 shared_ptr 也用到了引用計數來解決拷貝問題。

string 的寫時拷貝(維護乙個指標):

class

string

//拷貝構造

string

(const string& s)

:_str

(s._str)

,_pcount

(s._pcount)

//賦值運算子過載

string&

operator=(

const string& s)

_str = s._str;

_pcount = s._pcount;

(*_pcount)++;

}return

*this;}

~string()

}char

&operator

(size_t pos)

return _str[pos];}

const

char

*c_str()

private

:char

* _str;

int* _pcount;

};

原始碼中的寫法:在空間的頭部維護四個位元組的空間,記錄引用的個數。放在頭部維護效率能高一些,如果放在尾部維護的話,每次開闢新的空間都要講這四個位元組也向後挪動相應的位置,所以放在前面效率高點

class

string

//拷貝構造

string

(const string& s)

:_str

(s._str)

//賦值運算子過載

string&

operator=(

const string& s)

_str = s._str;

getrefcount()

++;}return

*this;}

~string()

}char

&operator

(size_t pos)

return _str[pos];}

int&

getrefcount()

private

:char

* _str;

};

寫時複製技術(COW)

維基百科 寫入時複製 copy on write 是乙個被使用在程式設計領域的最佳化策略。其基礎的觀念是,如果有多個呼叫者 callers 同時要求相同資源,他們會共同取得相同的指標指向相同的資源,直到某個呼叫者 caller 嘗試修改資源時,系統才會真正複製乙個副本 private copy 給該...

寫時拷貝技術

cow技術初窺 在linux程式中,fork 會產生乙個和父程序完全相同的子程序,但子程序在此後多會exec系統呼叫,出於效率考慮,linux中引入了 寫時複製 技術,也就是只有程序空間的各段的內容要發生變化時,才會將父程序的內容複製乙份給子程序。那麼子程序的物理空間沒有 怎麼去取指令執行exec系...

寫時拷貝技術

寫時拷貝故名思意 是在寫的時候 即改變字串的時候 才會真正的開闢空間拷貝 深拷貝 如果只是對資料的讀時,只會對資料進行淺拷貝 寫時拷貝技術是通過 引用計數 實現的,在分配空間的時候多分配4個位元組,用來記錄有多少個指標指向塊空間,當有新的指標指向這塊空間時,引用計數加一,當要釋放這塊空間時,引用計數...