神奇的fork(父子進程中一些神奇的問題)

在閱讀這篇文章的時候我希望長話短說,需要你事先接收一個觀點,那就是:我們的操作系統(tǒng)就是一堆進程,每一個進程都是由已有的進程創(chuàng)造出來的。

以linux操作系統(tǒng)為例,在啟動之后第一個誕生的進程是PID為0的名叫“idle”的進程,后續(xù)所有的進程都是由它通過fork()創(chuàng)建的,包括我們熟知的PID為1的“init”進程。也許一杯咖啡的時間,等系統(tǒng)完全啟動,我們可以登錄以后,在命令行執(zhí)行我們自己寫的程序,這又是通過終端進程創(chuàng)建了新的進程。這就是在前面所說的操作系統(tǒng)的運行就是進程的不斷創(chuàng)建和銷毀的過程。

在linux系統(tǒng)函數(shù)中,fork()是用來創(chuàng)建新的子進程的函數(shù)。根據(jù)linux編程手冊,在fork函數(shù)執(zhí)行完畢后,如果創(chuàng)建新進程成功,則出現(xiàn)兩個進程,一個是子進程,一個是父進程。在子進程中,fork函數(shù)返回0,在父進程中,fork返回新創(chuàng)建子進程的進程ID。我們可以通過fork返回的值來判斷當前進程是子進程還是父進程。

需要注意的是,在fork之后兩個進程用的是相同的物理空間(內(nèi)存區(qū)),子進程的代碼段、數(shù)據(jù)段、堆棧都是指向父進程的物理空間,也就是說,兩者的虛擬空間不同,其對應的物理空間是一個。這是出于效率的考慮,在linux中被稱為“寫時復制”(COW)技術(shù),只有當父子進程中有更改相應段的行為發(fā)生時,再為子進程相應的段分配物理空間。另外fork之后內(nèi)核會將子進程排在隊列的前面,以讓子進程先執(zhí)行,以免父進程執(zhí)行導致寫時復制,而后子進程執(zhí)行exec系統(tǒng)調(diào)用,因無意義的復制而造成效率的下降。

有關(guān)父子進程和fork的概念介紹完了,在這里想繼續(xù)分享一道很有意思的筆試題。

寫出下面程序的運行結(jié)果:

int main()
{
       pid_t cld_pid;
       int status;
       int a=1,b=2;
       for(int i = 0; i < 2; i++ ){
              if ((cld_pid = fork()) == 0){
                     a+=1;
                     printf("a=%d\n",a);
              }
              else{
                     b+=1;
                     printf("b=%d\n",b);
              }
       }
       wait(&status);
       return 0;
}

這其實就是考察了如果一個進程在for循環(huán)進行fork,會產(chǎn)生什么樣的結(jié)果,哪些變量的值已經(jīng)改變,哪些變量的值沒有改變。


分析

實際上它的運行一共產(chǎn)生了三個子進程:

首先父進程fork出了子進程1,同時自己執(zhí)行了b自加和打印,得到“b=3”。此時在第一輪循環(huán)中,子進程1的變量分別為i=0,a=1,b=2。第二輪循環(huán)中,創(chuàng)建了子進程2,同時執(zhí)行b的自加和打印,得到“b=4”,耗盡循環(huán)條件。而子進程2的變量為i=1,a=1,b=3。

對于子進程1,會執(zhí)行a的自加和打印,得到“a=2”,完成第一輪循環(huán)。在第二輪循環(huán)中創(chuàng)建了子子進程1,并對b自加和打印,得到“b=3”。子子進程1的變量分別為i=1,a=2,b=2。

對于子進程2,會執(zhí)行a的自加和打印,得到“a=2”,然后由于i=1,結(jié)束。

對于子子進程1,會執(zhí)行a的自加和打印,得到“a=3”,而由于i已經(jīng)為1,再也沒有新的循環(huán)了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 專業(yè)考題類型管理運行工作負責人一般作業(yè)考題內(nèi)容選項A選項B選項C選項D選項E選項F正確答案 變電單選GYSZ本規(guī)程...
    小白兔去釣魚閱讀 10,724評論 0 13
  • 1.內(nèi)存的頁面置換算法 (1)最佳置換算法(OPT)(理想置換算法):從主存中移出永遠不再需要的頁面;如無這樣的...
    杰倫哎呦哎呦閱讀 3,613評論 1 9
  • 引用:CSDN jason314 一、fork入門知識 一個進程,包括代碼、數(shù)據(jù)和分配給進程的資源。fork()函...
    _Nullptr閱讀 21,056評論 1 19
  • 原文地址:http://www.cnblogs.com/bastard/p/2664896.html 一、fork...
    Caiaolun閱讀 460評論 1 1
  • 徒弟小董 新進之教員 有幸成其教學上之師傅 感受到壓力 我雖年長 業(yè)務未必精通 虛名與經(jīng)驗稍許 與其共處時光 徒為...
    一度一閱讀 211評論 0 0

友情鏈接更多精彩內(nèi)容