天天看點

linux學習之十---vfork()&fork()函數

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()

linux學習之十---vfork()&amp;fork()函數

vfork()

linux學習之十---vfork()&amp;fork()函數

運作分析:

1.使用fork建立子程序時,子程序繼承立父程序的全局變量與局部變量。

子程序中,最後全局變量glodar和局部變量Var的值均遞增3,分别為8和4;

而父程序中,兩個變量分别遞增5,分别為10和6;

這證明了fork的子程序有自己獨立的位址空間,不管是全局變量還是局部變量,子程序與父程序對它們的修改互不影響。

2.vfork建立了子程序後,父程序中的glodVar和Var最後均遞增了8,這是因為vfork的子程序共享父程序的位址空間,子程序修改變量對父程序是可見的。

3.用fork建立了程序後,父程序與子程序是交替執行的;而使用vfork建立子程序後,列印結果是子程序在前,父程序在後,說明vfork保證子程序先執行,在子程序調用exit或exec之前父程序處于阻塞等待狀态。

繼續閱讀