fork()與vfork()函式
fork()與vfork()函式
1 fork()函式
建立一個和當前程式映像一樣的程式。
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
失敗返回-1;成功返回:父程式返回子程式的程式ID(非負);子程式返回0。
fork會產生一個和父程式完全相同的子程式。Linux中引入了“寫時複製”技術,只有程式空間的各段的內容要發生變化時,才會將程式的內容複製一份給子程式。
在fork之後exec之前兩個程式用的是相同的物理空間(記憶體區),子程式的程式碼段、資料段、堆疊都是指向父程式的物理空間,也就是說,兩者的虛擬空間不同,但其對應的物理空間是同一個。當父子程式中有更改相應段分配物理空間,如果不是因為exec,核心會給子程式的資料段、堆疊段分配相應的物理空間(至此兩者有各自的程式空間,互不影響),而程式碼段繼續共享父程式的物理空間(兩者的程式碼完全相同)。而如果是因為exec,由於兩者執行的程式碼不同,子程式的程式碼段也會分配單獨的物理空間。
2 父程式fork()後父子程式共享的內容
fork之後,子程式會拷貝父程式的資料空間、堆和棧空間(實際上是採用寫時複製技術),二者共享程式碼段。所以在子程式中修改全域性變數(區域性變數,分配在堆上的記憶體同樣也是)後,父程式的相同的全域性變數不會改變。
父子相同之處:全域性變數、.data、.text、棧、堆、環境變數、使用者ID、宿主目錄、程式工作目錄、訊號處理方式….
父子不同之處:程式ID、fork返回值、父程式ID、程式執行時間、鬧鐘、未決訊號集
父子程式共享:1.檔案描述符(開啟檔案的結構體)2.mmap建立的對映區。
不同程式開啟同一個檔案,程式表和檔案表的關係如下圖所示:
程式所開啟檔案和在fork後的結構圖如下所示,子程式是共享父程式的檔案表項。
3 fork()的原理
fork()-->clone()-->do_fork()-->copy_process()
fork()呼叫clone(),clone()呼叫do_fork(),do_fork()呼叫copy_process(),子程式會拷貝父程式的核心棧,thread_info,task_struct,開啟的檔案描述符等。它採用的是copy_on_write機制,即拷貝的只是父程式的虛擬空間但指向同一個實體記憶體。只有在更改段的情況下才會真正的複製實體記憶體。
4 vfork()函式
#incldue <sys/types.h>
#include <unistd.h>
pid_t vfork(void);
vfork()用於建立一個新程式,而新程式的目的是exec一個新程式。vfork()會掛起父程式直到子程式終止或者執行了一個新的可執行檔案的映像。vfork()和fork()一樣都建立一個子程式,但是它並不將父程式的地址空間完全複製到子程式中,因為子程式會立即呼叫exec或exit,於是也就不會存放改地址空間。相反,在子程式呼叫exec或exit之前,它在父程式的空間中執行。如果在呼叫這兩個函式之前子程式依賴於父程式的進一步動作,則會導致死鎖。
5 vfork()和fork()之間的區別:
- vfork()保證子程式先執行,在呼叫exec或者exit之前與父程式資料是共享的,在它呼叫exec或exit之後父程式才可能被排程執行;fork()建立子程式後會複製父程式的虛擬空間,但實體記憶體都是指向同一個,它是兩個同時執行的。
- 如果在呼叫exec或exit之前子程式依賴於父程式的進一步動作,則會導致死鎖。
- fork()的父子程式執行次序不確定;vfork()保證子程式先執行,在呼叫exec或者exit之前與父程式資料是共享的,在它呼叫exec或exit之後父程式才可能被排程執行。
相關文章
- 程式中fork和vfork的區別
- 理解 pcntl_fork 函式函式
- 研究linux函式 之 fork()Linux函式
- 作業系統---之fork()函式作業系統函式
- 【多程式】Linux中fork()函式詳解|多程式Linux函式
- Linux vfork()Linux
- fork函式的學習--深入瞭解計算機系統函式計算機
- Python函式與lambda 表示式(匿名函式)Python函式
- Oracle分析函式與視窗函式Oracle函式
- 建構函式與解構函式函式
- 函式節流與函式防抖函式
- 回撥函式 與 函式閉包函式
- 何時使用函式表示式與函式宣告函式
- echo與函式函式
- webgl內建函式--幾何函式與矩陣函式Web函式矩陣
- webgl內建函式--向量函式與紋理查詢函式Web函式
- 函式與極限 第一節 對映與函式函式
- 函式外與函式內的變數函式變數
- 普通函式與函式模板呼叫規則函式
- 箭頭函式與普通函式區別函式
- python內建函式-eval()函式與exec()函式的區別Python函式
- 生成函式與多項式函式
- 函式遞迴與生成式函式遞迴
- 函式宣告與函式表示式有什麼區別?函式
- 建構函式與普通函式的區別函式
- C++中函式指標與函式物件C++函式指標物件
- 箭頭函式與普通函式的區別函式
- 15.3 極限函式與和函式性質函式
- 普通函式與函式模板呼叫規則2函式
- SUBSTRING() 與 CONV() 函式函式
- JavaScript | 函式與方法JavaScript函式
- insert()與substr()函式函式
- 函式正規化入門(惰性求值與函式式狀態)函式
- JavaScript的迭代函式與迭代函式的實現JavaScript函式
- 深入理解函式節流與函式防抖函式
- 第 8 節:函式-函式型別與作用域函式型別
- fill函式與memset函式的區別(c++)函式C++
- PHP筆記:建構函式與解構函式PHP筆記函式