vfork用于創(chuàng)建一個(gè)新進(jìn)程,而該新進(jìn)程的目的是exec一個(gè)新進(jìn)程,vfork和fork一樣都創(chuàng)建一個(gè)子進(jìn)程,
但是它并不將父進(jìn)程的地址空間完全復(fù)制到子進(jìn)程中,不會(huì)復(fù)制頁(yè)表。因?yàn)樽舆M(jìn)程會(huì)立即調(diào)用exec,于
是也就不會(huì)存放該地址空間。不過(guò)在子進(jìn)程中調(diào)用exec或exit之前,他在父進(jìn)程的空間中運(yùn)行。為什么會(huì)有vfork,因?yàn)橐郧暗膄ork當(dāng)它創(chuàng)建一個(gè)子進(jìn)程時(shí),將會(huì)創(chuàng)建一個(gè)新的地址空間,并且拷貝父
進(jìn)程的資源,而往往在子進(jìn)程中會(huì)執(zhí)行exec調(diào)用,這樣,前面的拷貝工作就是白費(fèi)力氣了,這種情況下,
聰明的人就想出了vfork,它產(chǎn)生的子進(jìn)程剛開(kāi)始暫時(shí)與父進(jìn)程共享地址空間(其實(shí)就是線程的概念了),
因?yàn)檫@時(shí)候子進(jìn)程在父進(jìn)程的地址空間中運(yùn)行,所以子進(jìn)程不能進(jìn)行寫(xiě)操作,并且在兒子“霸占”著老子
的房子時(shí)候,要委屈老子一下了,讓他在外面歇著(阻塞),一旦兒子執(zhí)行了exec或者exit后,相當(dāng)于兒
子買了自己的房子了,這時(shí)候就相當(dāng)于分家了。vfork和fork之間的另一個(gè)區(qū)別是: vfork保證子進(jìn)程先運(yùn)行,在她調(diào)用exec或exit之后父進(jìn)程才可能被
調(diào)度運(yùn)行。如果在調(diào)用這兩個(gè)函數(shù)之前子進(jìn)程依賴于父進(jìn)程的進(jìn)一步動(dòng)作,則會(huì)導(dǎo)致死鎖。
由此可見(jiàn),這個(gè)系統(tǒng)調(diào)用是用來(lái)啟動(dòng)一個(gè)新的應(yīng)用程序。其次,子進(jìn)程在vfork()返回后直接運(yùn)行在父進(jìn)
程的??臻g,并使用父進(jìn)程的內(nèi)存和數(shù)據(jù)。這意味著子進(jìn)程可能破壞父進(jìn)程的數(shù)據(jù)結(jié)構(gòu)或棧,造成失敗。
為了避免這些問(wèn)題,需要確保一旦調(diào)用vfork(),子進(jìn)程就不從當(dāng)前的??蚣苤蟹祷?,并且如果子進(jìn)程改
變了父進(jìn)程的數(shù)據(jù)結(jié)構(gòu)就不能調(diào)用exit函數(shù)。子進(jìn)程還必須避免改變?nèi)謹(jǐn)?shù)據(jù)結(jié)構(gòu)或全局變量中的任何
信息,因?yàn)檫@些改變都有可能使父進(jìn)程不能繼續(xù)。通常,如果應(yīng)用程序不是在fork()之后立即調(diào)用exec(),就有必要在fork()被替換成vfork()之前做仔細(xì)
的檢查。用fork函數(shù)創(chuàng)建子進(jìn)程后,子進(jìn)程往往要調(diào)用一種exec函數(shù)以執(zhí)行另一個(gè)程序,當(dāng)進(jìn)程調(diào)用一種exec函
數(shù)時(shí),該進(jìn)程完全由新程序代換,而新程序則從其main函數(shù)開(kāi)始執(zhí)行,因?yàn)檎{(diào)用exec并不創(chuàng)建新進(jìn)程,
所以前后的進(jìn)程id 并未改變,exec只是用另一個(gè)新程序替換了當(dāng)前進(jìn)程的正文,數(shù)據(jù),堆和棧段。
聯(lián)系客服