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 ;
}
運作上面這段代碼:
可以看到本該輸出2行最終卻無限輸出!
如果将子程序中的return換成exit最終得到我們想要的輸出結果。
————————————————————————————————
為什麼 return 會挂掉而 exit 不會?
fork與vfork的差別:
- fork建立的子程序複制父程序的位址空間類容,包括資料段和堆棧段。
- vfork建立的子程序與父程序共享位址空間,包括代碼段、資料段和堆棧段。
vfork會保證子程序先運作,當子程序調用exec或者exit後父程序才接着往下執行。
在上面的程式中,由于子程序與父程序共享位址空間,當子程序結束時調用return時函數棧傳回并被彈出。是以父程序結束時将無法傳回,會再次調用main函數進而導緻循環!而exit隻會傳回進而保證了父程序結束時能夠正常傳回。
以上分析可知vfork建立子程序省去了複制父程序位址空間的開銷,大大的提高了運作效率,但是同時又存在潛在的危險。fork雖然不存在這個問題但是效率較低。是以之後fork用到了寫時複制進行了優化,提高了安全性的同時也兼顧了效率!