国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Linux > 正文

詳解linux中fork、vfork、clone函數的區別

2020-10-28 18:46:19
字體:
來源:轉載
供稿:網友

在linux系統中,fork(),vfork()和clone函數都可以創建一個進程,但是它們的區別是什么呢???本文就這三者做一個較深入的分析?。?!

1.fork()

  fork()函數的作用是創建一個新進程,由fork創建的進程稱為子進程,fork函數調用一次返回兩次,子進程返回值為0,父進程返回子進程的進程ID。我們知道,一個進程的地

址空間主要由代碼段,數據段,堆和棧構成,那么p2就要復制相關的段到物理內存。原始的unix系統的實現的是一種傻

瓜式的進程創建,這些復制包括:

(1) 為子進程的頁表分配頁面,確定頁表的位置;

(2)為子進程的頁分配頁面,確定子進程頁面的位置;

(3)初始化子進程的頁表;

(4)把父進程的頁復制到子進程對應的頁中

從圖中我們可以看出除了正文段外,子進程的所有其它段都分配了物理空間,并將父進程的相關內容拷貝過來。父進程的task_struct結構中的打開文件描述符,進程組ID,

回話ID都進行復制。

下面通過簡單的代碼檢測一下fork()函數:

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys types.h="">#include <pthread.h>#include #include <iostream>using namespace std;int main() {  int num = 1;  int child;  if(!(child =fork())) {  cout<<&num<<endl; address:="" alt="/" child="vfork()))" class="brush:java;" else="" father="" img="" include="" int="" is:="" namespace="" num="1;" num:="" pid="" pre="" son="" src="/uploadfile/Collfiles/20170421/201704210949041534.jpg" sys="" types.h="" using=""><p>測試結果:</p><p><img alt="/" src="/uploadfile/Collfiles/20170421/201704210949041535.jpg" style="width: 630px; height: 201.393px;"></p><p>從測試結果中我們可以看到,在子進程修改了num變量的值后,父進程的num的值也發生改變,說明對于子進程和父進程來說,它們操作的是同一個地方的num值,下面就是vfork的示意圖:</p><p><img alt="/" src="/uploadfile/Collfiles/20170421/201704210949041536.jpg" style="width: 508px; height: 375px;"></p><p>可以看出子進程直接共享了父進程的虛擬進程空間。</p><p>3.clone()</p><p>  clone()函數是linux系統中,用來創建輕量級進程。</p><p>函數原形:</p><pre class="brush:java;">int clone(int (*fn)(void *), void *child_stack, int flags, void *arg);下面是flags可以取的值標志     含義CLONE_PARENT 創建的子進程的父進程是調用者的父進程,新進程與創建它的進程成了“兄弟”而不是“父子”CLONE_FS   子進程與父進程共享相同的文件系統,包括root、當前目錄、umaskCLONE_FILES  子進程與父進程共享相同的文件描述符(file descriptor)表CLONE_NEWNS 在新的namespace啟動子進程,namespace描述了進程的文件hierarchyCLONE_SIGHAND 子進程與父進程共享相同的信號處理(signal handler)表CLONE_PTRACE 若父進程被trace,子進程也被traceCLONE_VFORK  父進程被掛起,直至子進程釋放虛擬內存資源CLONE_VM   子進程與父進程運行于相同的內存空間CLONE_PID   子進程在創建時PID與父進程一致CLONE_THREAD Linux 2.4中增加以支持POSIX線程標準,子進程與父進程共享相同的線程群下面的例子是創建一個線程(子進程共享了父進程虛存空間,沒有自己獨立的虛存空間不能稱其為進程)。父進程被掛起當子線程釋放虛存資源后再繼續執行。</pre>測試代碼1:<pre class="brush:java;">#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys types.h="">#include <pthread.h>#include #include <iostream>using namespace std;#define FIBER_STACK 8192int a;void * stack;int func(void *){ cout<<&a<<endl; a="" char="" creating="" int="" is="" is:="" my="" pid="" pre="" son="" stack="" the="" this="" void="">結果:<p><img alt="/" src="/uploadfile/Collfiles/20170421/201704210949041537.png" style="width: 630px; height: 201.393px;"></p><p>測試代碼2(做如下修改):</p><pre class="brush:java;">clone(func, (char *)stack + FIBER_STACK,CLONE_VFORK, 0);</pre>結果:<p><img alt="/" src="http://m.survivalescaperooms.com/uploadfile/Collfiles/20170421/201704210949041538.png" style="display: block; width: 630px; height: 201.393px;"></p><p>很明顯,在測試2中將CLONE_VM刪掉之后,子進程和父進程就不會公用頁表,子進程創建新的頁表。從某種意義上來說,clone其實是fork和vfrok的更高層次版本,,它們的關</p><p>系如下(《深入理解linux內核》中描述):</p><p>   <strong>傳統的fork()系統調用在Linux中是用clone()實現的,其中clone()的flags參數指定為sigchld信號以及所有清0的clone標志,而它的child_stack參數是父進程當前的堆棧</strong></p><p><strong>指針,因此,父進程和子進程暫時共享一個用戶態堆棧。而vfork函數系統調用也是用clone實現的,其中clone()的參數flags指定為sigchld和CLONE_VFORK和CLONE_VM標</strong></p><p><strong>志,clone()的參數child_stack等于父進程當前的棧指針?。?!</strong></p>。只是有一點不明白,把int a和void * stack挪到main函數里面之后,就會出現編譯錯誤,顯示未定義a和stack,這點有些不懂,望高人指點!?。。?</endl;></iostream></assert.h></pthread.h></sys></unistd.h></stdlib.h></stdio.h></pre></endl;></iostream></assert.h></pthread.h></sys></unistd.h></stdlib.h></stdio.h>

以上所述是小編給大家介紹的linux中fork、vfork、clone函數的區別,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 武山县| 皮山县| 渭南市| 旬阳县| 临沂市| 沂源县| 普定县| 永靖县| 临江市| 西乡县| 河源市| 永昌县| 荥经县| 舒城县| 阿巴嘎旗| 遂川县| 南平市| 伊金霍洛旗| 名山县| 扎赉特旗| 河津市| 彩票| 遂平县| 静乐县| 沅陵县| 黑山县| 静宁县| 旌德县| 彭州市| 淄博市| 奉节县| 灵台县| 乐业县| 怀集县| 化州市| 锡林浩特市| 阿拉善右旗| 钦州市| 南川市| 察雅县| 贡山|