1. 程式人生 > 其它 >fork與vfork的區別(注:vfork子程序不能return)(轉)

fork與vfork的區別(注:vfork子程序不能return)(轉)

1.vfork保證子程序先執行,在它呼叫exec或exit之後父程序才可能被排程執行。如果在呼叫這兩個函式之前子程序依賴於父程序的進一步動作,則會導致死鎖。

2.fork要拷貝父程序的程序環境;而vfork則不需要完全拷貝父程序的程序環境,在子程序沒有呼叫exec和exit之前,子程序與父程序共享程序環境,相當於執行緒的概念,此時父程序阻塞等待。

為什麼會有vfork呢?

因為以前的fork當它建立一個子程序時,將會建立一個新的地址空間,並且拷貝父程序的資源,然後將會有兩種行為:

1.執行從父程序那裡拷貝過來的程式碼段

2.呼叫一個exec執行一個新的程式碼段

當程序呼叫exec函式時,一個新程式替換了當前程序的正文,資料,堆和棧段。這樣,前面的拷貝工作就是白費力氣了,這種情況下,聰明的人就想出了vfork。vfork並不複製父程序的程序環境,子程序在父程序的地址空間中執行,所以子程序不能進行寫操作,並且在兒子“霸佔”著老子的房子時候,要委屈老子一下了,讓他在外面歇著(阻塞),一旦兒子執行了exec或者exit後,相當於兒子買了自己的房子了,這時候就相當於分家了。

因此,如果建立子程序是為了呼叫exec執行一個新的程式的時候,就應該使用vfork

fork:拷貝了一份父程序的資料,也就是說父子之間互不干涉

vfork:與父程序共享同一份資料

程式參考:

#include
#include
#include
int main(void) {
int var;
var = 88;
pid_t pid;
if ((pid = fork()) < 0) {
printf( "vfork error");
exit( -1);
} else if (pid == 0) { /* 子程序 */
var++;
printf( "pid=%d,var=%d\n"
, getpid(), var); return 0; //exit(0); } printf( "pid=%d,var=%d\n", getpid(), var); return 0;

執行結果:

pid= 4684,var= 89
pid= 4683,var= 88

因為此處用的是fork,所以父子之間互不干涉。

子程序中的var加一後,變為89。

而父程序中的var依然為88。

如果改為vfork,結果為:

pid= 4785,var= 89
pid= 4784,var= 89

因為共享資料了。

如果直接貼上上述程式碼,只將fork改為vfork,會出現段錯誤。

原因是,在fork中用return語句是允許的。

因為子程序是複製了一份資料。

然而,在vfork中用return語句,因為父子共享,則會導致棧的崩潰。

也就是父程序不能夠繼續執行下去了。

因此,在vfork中需要用exit()函式。

轉自:https://www.huaweicloud.com/zhishi/arc-9555487.html

聯絡方式:emhhbmdfbGlhbmcxOTkxQDEyNi5jb20=