父子程序資料共享問題

2021-06-19 15:18:24 字數 1486 閱讀 1409

1、fork

[cpp]view plain

copy

#include 

#include 

pid_t fork (void

);  

正確返回:父程序中返回子程序的程序號;子程序中返回0

錯誤返回:-1;

子程序是父程序的乙個拷貝。子程序從父程序那得到了資料段和堆疊段,但不是與父程序共享而是單獨分配記憶體。fork函式返回後,子程序和父程序都是從fork函式的下一條語句開始執行。

由於子程序與父程序的執行是無關的,父程序可先於子程序執行,子程序也可先於父程序執行。

fork在linux下使用了寫時複製技術,剛開始共享父程序的資料段,在寫資料段的時候才進行複製。

2、vfork

[cpp]view plain

copy

#include 

#include 

pid_t vfork (void

);  

返回值同上

vfork建立新程序的主要目的在於用exec函式執行另外的程式,實際上,在沒呼叫exec或exit之前子程序與父程序共享資料段。在vfork呼叫中,子程序先執行,父程序掛起,直到子程序呼叫exec或exit,在這以後,父子程序的執行順序不再有限制。

區別:

1、fork()建立的子程序是父程序的副本。即子程序獲取父程序資料空間,堆和 棧的副本。父子程序之間不共享這些儲存空間。而vfork()建立的程序並不將父程序的位址空間完全複製到子程序中,因為子程序會立即呼叫exec(或exit),於是也就不會存放該位址空間。相反,在子程序呼叫exec或exit之前,它在父程序的空間進行。

2、vfork()與fork()另乙個區別就是:vfork保證子程序先執行,在呼叫exec或exit之前與父程序資料是共享的,在它呼叫exec或exit之後父程序才可能被排程執行;而fork的父子程序是同級別的,沒有前後限制。vfork保證子程序先執行,如果子程序依賴於父程序的進一步動作,則會導致死鎖。

3、例項:

a、現在 p1 用 fork() 函式為程序建立乙個子程序 p2 ,核心:( 1 )複製 p1 的**段(正文段),資料段,堆,棧這四個部分。( 2)為這四個部分分配物理塊, p2 的**段指向p1的**段的物理塊,其實就是不為 p2 分配**段塊,資料段指向p2 自己的資料段(為其分配對應的塊),堆指向 p2 自己的堆,棧指向p2 自己的棧。如下圖所示:同左到右大的方向箭頭表示複製內容。

圖1

b、寫時複製技術:核心只為新生成的子程序建立虛擬空間,它們來複製于父程序的虛擬空間,但是不為這些段分配物理空間,它們共享父程序的物理空間,當父子程序中有寫記憶體的行為發生時,再為子程序相應的段分配物理空間。

圖2

c、 vfork() :這個更加激進,子程序的虛擬位址空間也不用建立,直接共享父程序的虛擬空間。這也是為後續的exec執行刪除了不必要的複製。

父子程序共享的資源

先來看乙個題目 當父程序呼叫fork 建立子程序之後,下列哪些變數在子程序中修改之後,父程序裡也會相應地作出改動?a.全域性變數 b.區域性變數 c.靜態變數 d.檔案指標 答案為d,解釋如下 fork 子程序和父程序共享的資源 開啟的檔案 實際使用者id 實際組 id 有效使用者 id 有效組 i...

共享記憶體實現父子程序通訊

父程序在核心空間建立了乙個共享記憶體,通過fork函式,父子程序通過fork函式繼承了shmid,所以父子程序可以對核心中同乙個物件操作,剛開始父程序不斷往物件裡寫,然後開始發訊號sigusr1給子程序,讓子程序讀。對於子程序來說,剛開始睡眠,等待父程序寫,然後被核心喚醒,讀共享記憶體。此時父程序開...

Linux父子程序之間的資料共享分析

全域性變數 棧區 區域性變數 堆區 動態開闢 檔案 不共享 不共享 不共享 共享檔案偏移量1.在fork之前開啟檔案的話,那麼fork之後父子程序的檔案描述符fd相同。2.父子程序檔案描述符是共享的,但是關閉的時候可以分別關閉,也可以同時在公有 中關閉,類似於引用計數,只不過是被不同程序所引用。參考...