return x與exit(x)到底有什麼區別
書中說main函數return相當於
exit(main(argc,argv))
但實踐中出了點問題
運行結果:
如果把exit換成return確不會。
基礎知識
首先說說fork與vfork的區別
●fork 創建一個進程,並把父進程內存數據copy拷貝到子進程去。
●vfork 創建一個進程,並和父進程的內存數據share一起用。
兩個區別是:一個share,一個是copy。
man fork 一下,發現vfork是這樣工作的:
(1)保證子進程先執行
(2)當子進程調用exit()或exec()後,父進程往下執行。
那麼,爲什麼那麼,要存在vfork?(存在即合理) 原因是這樣的—— 起初只有fork,但是很多程序在fork一個子進程後就exec一個外部程序,於是fork需要copy父進程的數據這個動作就變得毫無意了,而且還很 重,所以,搞出了個父子進程共享的vfork。所以,vfork本就是爲了exec而生。
爲什麼return會掛掉,exit確不會
從上面我們知道,結束子進程用exit()而不是return,注意,你在vfork中return了,那麼,就意味着main函數中retun了,因爲父子進程共享函數棧,所以整個函數棧就跪了。
如果在子進程中return了,基本上是一下過程:
子進程的main()函數return了
而main()函數return了,通常會調用exit()或相似的函數。
這時父進程收到子進程exit(),開始從vfork返回,但是此時棧已被破壞,(注:棧會返回一個詭異一個棧地址,對於某些內核版本的實現,直接報“棧錯誤”就給跪了,然而,對於某些內核版本的實現,於是有可能會再次調用main(),於是進入了一個無限循環的結果,直到vfork 調用返回 error)
如圖所示:
總結:returnh會釋放局部變量並彈棧,回到上級函數執行,exit()會直接退掉,如果用c++就會知道,return會調用局部對象的析構函數,exit()不會,(注:exit()不是系統調用,是glibc對系統調用 _exit()或_exitgroup()的封裝)
可見:子進程調用exit()函數沒有修改函數棧,所有,父進程得意順利執行