fork程序時資源的深拷貝和淺拷貝

2021-05-21 19:31:51 字數 1551 閱讀 4881

linux

(和unix

)將程序的概念說的很大,而且很細,程序不再僅僅擁有乙個執行流,而是有了乙個容器,其實某種意義上它本身就是乙個容器。

unix

傳統將程序想成

了乙個執行緒,概念真的就是如此簡單,簡單的東西往往是好的東西,複雜的反而會更加糟糕。程序概念的簡單性使得

fork

可以如此美妙如此簡單的實現,使得

建立乙個可執行映像可以分為

fork

和exec

,正如我的前文所述。更加重要的是,傳統

unix

將執行緒和執行過程中需要的資源分開了,如此就可以將資源

作為一件物品在程序之間傳遞,這絲毫沒有問題。

linux

繼承了unix

一切好的東西,它的程序由

task_struct

表示,內部有很多表示資源的字段,比如

files_struct

表示開啟的文

件,unix

中的fork

的意義就是程序複製,複製是如此的簡單且直觀,使得你只需要複製當前的一切就可以了,複製往往比創造要簡單得多,就像我們小的時

候總喜歡抄作業一樣,後來又有了寫時複製,更加節約了時間增加了效率,於是

fork

的意義就是複製一切資源,而對於執行緒內部的資源比如位址空間採取寫時

複製的策略。因此,檔案描述符作為開啟檔案的索引其實也是一種資源,這樣的話在

fork

的時候就可以傳遞給子程序了。

linux

就是這樣像叉子一樣不斷的

fork

最終形成一片天地。

linux

一向以位址空間的隔離作為其安全的根本,但是為何卻可以拿資源傳來傳去呢?位址空間不也是一種資源嗎?互相傳遞資源不會引起不安全嗎?當然不會

不安全,

linux

的程序結構設計的非常好,資源的共享完全在可控範圍內,也就是說你可以選擇傳遞或者不傳遞,一切由你決定,如果出了問題就是你自己造成

的而不是作業系統造成的。核心當然知道什麼東西是可以安全傳遞的,比如檔案描述符,該描述符對應的檔案可以被子程序隨意讀寫,而且檔案描述符可以不變,對

於位址空間,它是程序的根本,在

fork

的時候是完全複製的(現在是寫時複製),其實位址空間和檔案描述符都是資源,那為什麼核心對待它們的態度卻不同

呢?對於檔案描述符的複製是淺拷貝而對於位址空間的拷貝卻是深拷貝,

why?這就涉及到乙個資源性質的問題。我們看一下檔案和位址空間作為資源有何不同,

其實很容易就可以看出它們的不同,對於檔案是共享資源,它並不是程序的內稟屬性,程序可擁有可不擁有,因此它當然可以被共享,而對於位址空間,它是程序的

內稟屬性,程序的定義中明確規定位址空間不能和別的程序共享,因此它就必須被程序獨享,因此在

fork

的時候要深拷貝。舉個例子,丈夫這個定義,它表示此

人擁有乙個妻子,妻子就是他的乙個資源,而且他也可以擁有一支鋼筆,但是對於丈夫而言妻子是他的內稟屬性,因此妻子是他獨有的,但是鋼筆和丈夫並沒有必然

關係,因此鋼筆是可以讓別人用的。

淺拷貝,深拷貝,寫時拷貝

淺拷貝 拷貝構造時複製指標僅僅是對指標的值拷貝,而不開闢新的空間這樣就會造成在析構的時候。會對同一塊記憶體釋放兩次。深拷貝 拷貝構造時會開闢新的記憶體,並把記憶體中的值進行拷貝 寫時拷貝 就是當你在讀取一片空間時,系統並不會為你開闢乙個一模一樣的空間給你 只有在當你真正修改的時候,才會開闢一片空間給...

深拷貝 淺拷貝 寫時拷貝

在拷貝構造的時候,直接將原內容的位址交給要拷貝的類,兩個類共同指向一塊記憶體。缺陷 1 一旦對str2進行操作,str1的內容也會改變 2 析構時先析構str2,再析構str1,但是由於str1,str2指向同一塊記憶體空間,因此會導致對一塊記憶體進行兩次析構而出現錯誤 通過開闢和源空間大小相同的記...

淺拷貝,深拷貝,寫時拷貝

思想 我們用指標p申請了一塊記憶體空間,在用指標q指向了這一片記憶體空間,這時候這兩個指標指向的是同乙個記憶體空間,當需要釋放這塊記憶體空間的時候p會釋放一次,q也會釋放一次,這樣重複釋放就會引發程式的崩潰。我們通過一段 來理解淺拷貝 class person void test int main ...