return x與exit(x)到底有什麼區別

return x與exit(x)到底有什麼區別


書中說main函數return相當於

exit(main(argc,argv))

但實踐中出了點問題

wKiom1eZtWXy1j54AACljl2InyY807.png-wh_50

運行結果:

wKiom1eZvyHSkhj6AAAPvSfcC6k003.png-wh_50

如果把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了,基本上是一下過程:

  1. 子進程的main()函數return了

  2. 而main()函數return了,通常會調用exit()或相似的函數。

  3. 這時父進程收到子進程exit(),開始從vfork返回,但是此時棧已被破壞,(注:棧會返回一個詭異一個棧地址,對於某些內核版本的實現,直接報“棧錯誤”就給跪了,然而,對於某些內核版本的實現,於是有可能會再次調用main(),於是進入了一個無限循環的結果,直到vfork 調用返回 error)

如圖所示:

wKioL1eZvWjTMhzVAACRC2Wiw0U684.png-wh_50

總結:returnh會釋放局部變量並彈棧,回到上級函數執行,exit()會直接退掉,如果用c++就會知道,return會調用局部對象的析構函數,exit()不會,(注:exit()不是系統調用,是glibc對系統調用 _exit()或_exitgroup()的封裝)

可見:子進程調用exit()函數沒有修改函數棧,所有,父進程得意順利執行


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章