天天看點

vfork死循環問題

關于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和vfork的差别:
  • fork 是 建立一個子程序,并把父程序的記憶體資料copy到子程序中。
  • vfork是 建立一個子程序,并和父程序的記憶體資料share一起用。

這兩個的差别是,一個是copy,一個是share。

你 man vfork 一下,你可以看到,vfork是這樣的工作的,

1)保證子程序先執行。

2)當子程序調用exit()或exec()後,父程序往下執行。

問題來了,如果子程序沒有調用exit退出,而是return傳回,那麼在有些系統,例如CentOS上會陷入一個死循環當中,更有甚着,直接會報一個段錯誤,如Ubuntu上。這是為什麼呢?

在CentOS上:

木有配圖=_=|| 死循環!
在Ubuntu上:
vfork死循環問題
仔細分析過後,原因如下:
  1. 父子程序共享位址空間,子程序從main函數傳回後,背後又調用了exit(函數),如此父程序才會開始運作。
  2. return之後,此位址空間被銷毀,main函數棧幀被清退,運氣好的話(看系統版本)還是有可能繼續運作的,運氣不好就是段錯誤了。
  3. exit函數沒有清退棧幀,是以将return改為exit,父程序還可以繼續運作。
由此得出一個結論:vfork用的不好會坑爹!

繼續閱讀