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=