對於Linux多進程開發上篇文章講解了fork()創建進程,這一篇詳細講解下 vfork()創建進程。
vfork()和fork()有一點不同:
1.vfork()和fork()一樣,一次調用,兩次返回。
2.fork()創建一個子進程,子進程只是完全復制父進程的資源,這樣的子進程獨立於父進程,並發性好
3.vfork()創建一個子進程時,操作系統並不完全復制父進程的資源,vfork創建的資源共享父進程的地址空間,子進程完全運行在父進程的地址空間上,子進程對該地址空間中任何數據的修改同樣父進程
為父進程所見。
4.vfork()創建一個子進程時,哪個進程先運行取決於系統的調度算法,而vfork一個進程時,vfork保證
子進程先運行,當它調用exec或exit後,父進程才可能被調度運行。
注:如果在調用exec或exit之前子進程要依賴父進程的某個行為,就會導致死鎖。
下面用代碼講解:
# include <unistd.h> # include <sys/types.h> # include <stdio.h> int globVar = 5; int main(void) { pid_t pid; int var = 1, i; printf("fork is diffirent with vfork \n"); pid = fork(); /*pid = vfork()*/ switch(pid) { case 0: i = 3; while(i-- > 0) { printf("Child process is running \n"); globVar++; var++; sleep(1); } printf("Child's globVar = %d, var = %d\n",globVar, var); break; case -1: perror("Process creation failed \n"); exit(0); default: i = 5; while(i-- > 0) { printf("Parent process is runnig \n"); globVar++; var++; sleep(1); } printf("Parent's globVar = %d, var = %d\n", globVar, var); exit(0); } exit(0); }
此時運行結果如下:
此時用的是fork()創建新進程,分析:
子進程繼承了父進程的全局變量和局部變量,子進程中,最後全局變量globVar和局部變量var均遞增3,分別是8和4,而父進程均遞增5,結果是10和6,這證明了子進程有自己獨立的地址空間。不管是全局變量還是局部變量,子進程和父進程對它們的修改互不影響。
此時注釋帶掉pid = fork(); 開始用vfork(),結果如下:
分析:
vfork()創建了子進程後,父進程中globVar和var都遞增了8,因為vfork()的子進程共享父進程的地址空間,子進程修改變量對父進程是可見的。
fork()創建了子進程之後,父子進程的執行順序是不確定的。
vfork()創建子進程之後,子進程先運行,這是因為vfork()是保證子進程先運行的,在子進程調用exit或exec之前父進程是阻塞的狀態。
在進程中:S為阻塞狀態。 D為不可中斷狀態。
大家可以去ps下去看看。
特注:使用vfork時要謹慎,最好不要允許子進程修改與父進程共享的全局變量和局部變量。
本文出自 “_Liang_Happy_Life__Dream” 博客,請務必保留此出處http://liam2199.blog.51cto.com/2879872/1231680