您好,登錄后才能下訂單哦!
return x與exit(x)到底有什么區(qū)別
書中說(shuō)main函數(shù)return相當(dāng)于
exit(main(argc,argv))
但實(shí)踐中出了點(diǎn)問(wèn)題
運(yùn)行結(jié)果:
如果把exit換成return確不會(huì)。
基礎(chǔ)知識(shí)
首先說(shuō)說(shuō)fork與vfork的區(qū)別
●fork 創(chuàng)建一個(gè)進(jìn)程,并把父進(jìn)程內(nèi)存數(shù)據(jù)copy拷貝到子進(jìn)程去。
●vfork 創(chuàng)建一個(gè)進(jìn)程,并和父進(jìn)程的內(nèi)存數(shù)據(jù)share一起用。
兩個(gè)區(qū)別是:一個(gè)share,一個(gè)是copy。
man fork 一下,發(fā)現(xiàn)vfork是這樣工作的:
(1)保證子進(jìn)程先執(zhí)行
(2)當(dāng)子進(jìn)程調(diào)用exit()或exec()后,父進(jìn)程往下執(zhí)行。
那么,為什么那么,要存在vfork?(存在即合理) 原因是這樣的—— 起初只有fork,但是很多程序在fork一個(gè)子進(jìn)程后就exec一個(gè)外部程序,于是fork需要copy父進(jìn)程的數(shù)據(jù)這個(gè)動(dòng)作就變得毫無(wú)意了,而且還很 重,所以,搞出了個(gè)父子進(jìn)程共享的vfork。所以,vfork本就是為了exec而生。
為什么return會(huì)掛掉,exit確不會(huì)
從上面我們知道,結(jié)束子進(jìn)程用exit()而不是return,注意,你在vfork中return了,那么,就意味著main函數(shù)中retun了,因?yàn)楦缸舆M(jìn)程共享函數(shù)棧,所以整個(gè)函數(shù)棧就跪了。
如果在子進(jìn)程中return了,基本上是一下過(guò)程:
子進(jìn)程的main()函數(shù)return了
而main()函數(shù)return了,通常會(huì)調(diào)用exit()或相似的函數(shù)。
這時(shí)父進(jìn)程收到子進(jìn)程exit(),開始從vfork返回,但是此時(shí)棧已被破壞,(注:棧會(huì)返回一個(gè)詭異一個(gè)棧地址,對(duì)于某些內(nèi)核版本的實(shí)現(xiàn),直接報(bào)“棧錯(cuò)誤”就給跪了,然而,對(duì)于某些內(nèi)核版本的實(shí)現(xiàn),于是有可能會(huì)再次調(diào)用main(),于是進(jìn)入了一個(gè)無(wú)限循環(huán)的結(jié)果,直到vfork 調(diào)用返回 error)
如圖所示:
總結(jié):returnh會(huì)釋放局部變量并彈棧,回到上級(jí)函數(shù)執(zhí)行,exit()會(huì)直接退掉,如果用c++就會(huì)知道,return會(huì)調(diào)用局部對(duì)象的析構(gòu)函數(shù),exit()不會(huì),(注:exit()不是系統(tǒng)調(diào)用,是glibc對(duì)系統(tǒng)調(diào)用 _exit()或_exitgroup()的封裝)
可見:子進(jìn)程調(diào)用exit()函數(shù)沒有修改函數(shù)棧,所有,父進(jìn)程得意順利執(zhí)行
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。