vfork用於建立一個新進程,而該進程的目的就是exec一個新程式。vfork和fork均建立一個子進程,但是vfork並不將父進程的地址空間完全複製到子進程中,因為子進程會調用exec(或exit),於是也就不會訪問改地址空間。在子進程調用exec或exit之前,它繼續在父進程的空間中運行。
vfork和fork之間的另一個區別:vfork保證子進程先運行。在子進程調用exec或exit之後,父進程才可能被調度運行。
1 #include <stdlib.h> 2 #include <unistd.h> 3 #include <sys/types.h> 4 #include <stdio.h> 5 6 int global = 6; 7 8 int main() 9 {10 int var;11 pid_t pid;12 13 var = 88;14 printf("before vfork\n");15 printf("pid = %d, global = %d, var = %d\n", getpid(), global, var);16 17 if ((pid = vfork()) < 0)18 {19 perror(" failed to vfork()!\n");20 return -1;21 }22 else if (pid == 0)23 {24 printf(" After vfork, and in child process:\n");25 printf(" pid = %d, global = %d, var = %d\n", getpid(), global, var);26 27 global++;28 var++;29 _exit(0);30 }31 32 printf("\n\nAfter vfork, and in parent process:\n");33 printf(" pid = %d, global = %d, var = %d\n", getpid(), global, var);34 35 return 0;36 }
View Code
運行結果:
利用exec函數以執行一個程式。當進程調用一種exec函數時,該進程執行的程式完全替換為新進程,而新程式則從其main函數開始執行。不改變進程的ID,exec只是用一個全新的程式替換了當前進程的本文、資料、堆和棧段。
1 /* gcc echoall.c -o echoall */ 2 #include <stdlib.h> 3 #include <stdio.h> 4 5 int main(int argc, char **argv) 6 { 7 int i; 8 char **ptr; 9 extern char **environ;10 11 for (i = 0; i < argc; ++i)12 printf(" argv[%d]: %s\n", i, argv[i]);13 14 exit(0);15 }
View Code
將改程式編譯結果放置在/home/sunday/share/目錄中。
1 /* execDemo.c */ 2 #include <unistd.h> 3 #include <stdio.h> 4 #include <sys/types.h> 5 6 int main() 7 { 8 pid_t pid; 9 10 if ((pid = fork()) < 0)11 {12 printf(" fork error!\n");13 return -1;14 }15 else if (pid == 0)16 {17 printf(" Now in child process\n");18 printf(" And not leave parent room\n");19 if (execl("/home/sunday/share/echoall", "echoall", "myarg1",20 (char *) 0) < 0)21 {22 printf(" execle failed!\n");23 return -1;24 }25 }26 27 printf(" Now in parent process\n");28 return 0;29 }
View Code
運行結果: