關于vfork函數的一個問題。首先說一下fork和vfork的差别:#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> int main() { int g_val = 100; pid_t id = vfork(); if (id == 0) { g_val++; printf("child runing first...%d:%p\n", g_val, &g_val); sleep(1); //exit(0); return 0; } else { printf("father runing first...%d:%p\n", g_val, &g_val); } return 0; }
- fork 是 建立一個子程序,并把父程序的記憶體資料copy到子程序中。
- vfork是 建立一個子程序,并和父程序的記憶體資料share一起用。
這兩個的差别是,一個是copy,一個是share。
你 man vfork 一下,你可以看到,vfork是這樣的工作的,
1)保證子程序先執行。
2)當子程序調用exit()或exec()後,父程序往下執行。
問題來了,如果子程序沒有調用exit退出,而是return傳回,那麼在有些系統,例如CentOS上會陷入一個死循環當中,更有甚着,直接會報一個段錯誤,如Ubuntu上。這是為什麼呢?
在CentOS上:
木有配圖=_=|| 死循環!在Ubuntu上: 仔細分析過後,原因如下:由此得出一個結論:vfork用的不好會坑爹!
- 父子程序共享位址空間,子程序從main函數傳回後,背後又調用了exit(函數),如此父程序才會開始運作。
- return之後,此位址空間被銷毀,main函數棧幀被清退,運氣好的話(看系統版本)還是有可能繼續運作的,運氣不好就是段錯誤了。
- exit函數沒有清退棧幀,是以将return改為exit,父程序還可以繼續運作。