vfork()也可以用來建立一個新程序,與fork()函數一樣都是調用一次,傳回兩次,但它有自己的獨特之處,差別如下:
1.使用fork建立一個子程序,子程序完全複制父程序的資源,這樣得到的子程序獨立于父程序,具有良好的并發性。而使用vfork建立一個子程序,作業系統并不将父程序的位址可見完全複制到子程序,用vfork建立的子程序共享父程序的位址空間,也就是說子程序完全運作在父程序的位址空間上。子程序對該位址空間中任何資料的修改同樣為父程序所見。
2.使用fork建立一個子程序時,哪個程序先運作取決于系統的排程算法。而vfork一個程序時,vfork保證子程序先運作,當它調用exec或exit之後,父程序才可能被排程運作。如果在調用exec或exit之前子程序要依賴父程序的某個行為,就會導緻死鎖。
什麼時候用vfork?
因為使用fork建立一個子程序時,子程序需要将父程序幾乎每種資源都複制,是以fork是一個開銷很大的系統調用,這樣的開銷不是所有情況都需要的。比如fork一個程序後,立即調用exec執行另一個應用程式,那麼fork過程中子程序對父程序位址空間的複制将是一個多餘的過程。而vfork不拷貝父程序的位址空間,這大大減少立系統開銷。
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int glodVar = 5;
int main()
{
pid_t pid;
int Var=1,i;
printf("fork is different with vfork\n");
pid = fork();
//pid = vfork();
switch(pid)
{
case 0:
i=3;
while(i-->0)
{
printf("Child process is running\n");
glodVar++;
Var++;
sleep(1);
}
printf("Child's goldVar=%d,var=%d\n",glodVar,Var);
exit(0);
case -1:
perror("Process creation failed\n");
exit(0);
default:
i=5;
while(i-->0)
{
printf("Parent process is running\n");
glodVar++;
Var++;
sleep(1);
}
printf("Parent's goldVar=%d,var=%d\n",glodVar,Var);
exit(0);
}
return 0;
}
fork()

vfork()
運作分析:
1.使用fork建立子程序時,子程序繼承立父程序的全局變量與局部變量。
子程序中,最後全局變量glodar和局部變量Var的值均遞增3,分别為8和4;
而父程序中,兩個變量分别遞增5,分别為10和6;
這證明了fork的子程序有自己獨立的位址空間,不管是全局變量還是局部變量,子程序與父程序對它們的修改互不影響。
2.vfork建立了子程序後,父程序中的glodVar和Var最後均遞增了8,這是因為vfork的子程序共享父程序的位址空間,子程序修改變量對父程序是可見的。
3.用fork建立了程序後,父程序與子程序是交替執行的;而使用vfork建立子程序後,列印結果是子程序在前,父程序在後,說明vfork保證子程序先執行,在子程序調用exit或exec之前父程序處于阻塞等待狀态。