天天看點

程序中fork vfork的用法

在建立程序時,會用到fork 或vfork 建立子程序

1)copy- on write(fork)

      fork之後exec之前,父子程序的虛拟空間不同,但其對應的實體空間是同一個!

    兩個程序用的是相同的實體空間(記憶體區),子程序的代碼段、資料段、堆棧都是指向父程序的實體空間!  (從左往右的大箭頭表示的建立子程序的複制動作)

程式中fork vfork的用法

   當父子程序中有更改相應段的行為發生時,再為子程序相應的段配置設定實體空間!

   如果是在子程序中調用了exec,由于兩者執行的代碼不同,子程序的代碼段也會配置設定單獨的實體空間。

程式中fork vfork的用法

 fork函數建立子程序後,子程序往往要調用一種exec函數以執行另一個程式,當程序調用一種exec函數時,該程序完全由新程式代換,而新程式則從其main函數開始執行,因為調用exec并不建立新程序,是以前後的程序id 并未改變,exec隻是用另一個新程式替換了目前程序的正文,資料,堆和棧段。

2 ) vfork

1  vfork 不會将父程序的位址空間完全複制到子程序中,也不會複制頁表。在子程序調用ecec 或者exit的之前,子程式會在父程式的空間運作,父程序阻塞。挂起)

2  vfork保證子程序先運作(fork不能保證),在她調用exec或exit之後父程序才可能被排程運作。如果在調用這兩個函數之前子程序依賴于父程序的進一步動作,則會導緻死鎖。(從左到右的箭頭表示的是共享)

程式中fork vfork的用法

///

#include <sys/types.h>  
#include <unistd.h>  
#include <stdio.h>
#include <stdlib.h>
int glob = 6;  
int main()
{  
int var;  
pid_t pid;  
var = 88;  
printf("before fork\n");  
if((pid = fork()) < 0)
{  
    perror("fork");  
    return 1;  
}
else if(pid == 0)//   子程序
	{  
          glob++;  
          var++;  
          _exit(0);  
        }  
        else     //    父程序
	{
          printf("pid=%d,glob=%d,var=%d\n", getpid(),glob,var);  
          exit(0);
        }  
}
/* 
fork時,由于glob 和 val 沒有發生變化 ,說明父子程序在資料發生改變時,會獨立配置設定給子程序一塊兒實體空間。
vfork 兩個資料發生了改變,表示子程序在父程序空間中運作。
*/
           

結果:

before fork

father process pid=4681,glob=6,var=88

son process pid=4682,glob=7,var=89

#include <sys/types.h>  
#include <unistd.h>  
#include <stdio.h>
#include <stdlib.h>
int glob = 6;  
int main()
{  
int var;  
pid_t pid;  
var = 88;  
printf("before vfork\n");  
if((pid = vfork()) < 0)
{  
    perror("vfork");  
    return 1;  
}
else if(pid == 0)//   子程序
	{  
          glob++;  
          var++;  
	printf("son process pid=%d,glob=%d,var=%d\n", getpid(),glob,var); 
          _exit(0);  
        }  
        else     //    父程序
	{
          printf("father process pid=%d,glob=%d,var=%d\n", getpid(),glob,var);  
          exit(0);
        }  
}
           

結果:

before vfork

son process pid=4670,glob=7,var=89

father process pid=4669,glob=7,var=89

繼續閱讀