天天看點

vfork

vfork死循環分析

/***vfork.c***/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
   pid_t pid;
   pid = vfork();
   if(pid < ){
      perror("fail to vfork");
      exit();
   }else if(pid == ){
            printf("this is child\n");
            //exit(0);
            return ;
         }
         else printf("this is parent\n");

   return ;

}
           

運作上面這段代碼:

vfork

可以看到本該輸出2行最終卻無限輸出!

如果将子程序中的return換成exit最終得到我們想要的輸出結果。

————————————————————————————————

為什麼 return 會挂掉而 exit 不會?

fork與vfork的差別:

- fork建立的子程序複制父程序的位址空間類容,包括資料段和堆棧段。
- vfork建立的子程序與父程序共享位址空間,包括代碼段、資料段和堆棧段。
           

vfork會保證子程序先運作,當子程序調用exec或者exit後父程序才接着往下執行。

在上面的程式中,由于子程序與父程序共享位址空間,當子程序結束時調用return時函數棧傳回并被彈出。是以父程序結束時将無法傳回,會再次調用main函數進而導緻循環!而exit隻會傳回進而保證了父程序結束時能夠正常傳回。

以上分析可知vfork建立子程序省去了複制父程序位址空間的開銷,大大的提高了運作效率,但是同時又存在潛在的危險。fork雖然不存在這個問題但是效率較低。是以之後fork用到了寫時複制進行了優化,提高了安全性的同時也兼顧了效率!