Linux fork 機(jī)制

?? 今天一位朋友去一個(gè)不錯(cuò)的外企面試linux開發(fā)職位麸俘,面試官出了一個(gè)如下的題目:

????? 給出如下C程序齐板,在linux下使用gcc編譯:

????? 要求如下:

????? 已知從這個(gè)程序執(zhí)行到這個(gè)程序的所有進(jìn)程結(jié)束這個(gè)時(shí)間段內(nèi)吵瞻,沒有其它新進(jìn)程執(zhí)行葛菇。

????? 1、請說出執(zhí)行這個(gè)程序后橡羞,將一共運(yùn)行幾個(gè)進(jìn)程眯停。

????? 2、如果其中一個(gè)進(jìn)程的輸出結(jié)果是“pid1:1001, pid2:1002”卿泽,寫出其他進(jìn)程的輸出結(jié)果(不考慮進(jìn)程執(zhí)行順序)莺债。

????? 明顯這道題的目的是考察linux下fork的執(zhí)行機(jī)制。下面我們通過分析這個(gè)題目签夭,談?wù)刲inux下fork的運(yùn)行機(jī)制齐邦。

預(yù)備知識

????? 這里先列出一些必要的預(yù)備知識,對linux下進(jìn)程機(jī)制比較熟悉的朋友可以略過第租。

????? 1措拇、進(jìn)程可以看做程序的一次執(zhí)行過程。在linux下慎宾,每個(gè)進(jìn)程有唯一的PID標(biāo)識進(jìn)程丐吓。PID是一個(gè)從1到32768的正整數(shù),其中1一般是特殊進(jìn)程init趟据,其它進(jìn)程從2開始依次編號券犁。當(dāng)用完32768后,從2重新開始汹碱。

????? 2粘衬、linux中有一個(gè)叫進(jìn)程表的結(jié)構(gòu)用來存儲當(dāng)前正在運(yùn)行的進(jìn)程”缺唬可以使用“ps aux”命令查看所有正在運(yùn)行的進(jìn)程色难。

????? 3泼舱、進(jìn)程在linux中呈樹狀結(jié)構(gòu)等缀,init為根節(jié)點(diǎn),其它進(jìn)程均有父進(jìn)程娇昙,某進(jìn)程的父進(jìn)程就是啟動這個(gè)進(jìn)程的進(jìn)程尺迂,這個(gè)進(jìn)程叫做父進(jìn)程的子進(jìn)程。

????? 4冒掌、fork的作用是復(fù)制一個(gè)與當(dāng)前進(jìn)程一樣的進(jìn)程噪裕。新進(jìn)程的所有數(shù)據(jù)(變量、環(huán)境變量股毫、程序計(jì)數(shù)器等)數(shù)值都和原進(jìn)程一致膳音,但是是一個(gè)全新的進(jìn)程,并作為原進(jìn)程的子進(jìn)程铃诬。

解題的關(guān)鍵

????? 有了上面的預(yù)備知識祭陷,我們再來看看解題的關(guān)鍵苍凛。我認(rèn)為,解題的關(guān)鍵就是要認(rèn)識到fork將程序切成兩段兵志〈己看下圖:

????? 上圖表示一個(gè)含有fork的程序,而fork語句可以看成將程序切為A想罕、B兩個(gè)部分悠栓。然后整個(gè)程序會如下運(yùn)行:

????? step1、設(shè)由shell直接執(zhí)行程序按价,生成了進(jìn)程P惭适。P執(zhí)行完P(guān)art. A的所有代碼。

????? step2楼镐、當(dāng)執(zhí)行到pid = fork();時(shí)腥沽,P啟動一個(gè)進(jìn)程Q,Q是P的子進(jìn)程鸠蚪,和P是同一個(gè)程序的進(jìn)程今阳。Q繼承P的所有變量、環(huán)境變量茅信、程序計(jì)數(shù)器的當(dāng)前值盾舌。

????? step3、在P進(jìn)程中蘸鲸,fork()將Q的PID返回給變量pid妖谴,并繼續(xù)執(zhí)行Part. B的代碼。

????? step4酌摇、在進(jìn)程Q中膝舅,將0賦給pid,并繼續(xù)執(zhí)行Part. B的代碼窑多。

????? 這里有三個(gè)點(diǎn)非常關(guān)鍵:

????? 1仍稀、P執(zhí)行了所有程序,而Q只執(zhí)行了Part. B埂息,即fork()后面的程序技潘。(這是因?yàn)镼繼承了P的PC-程序計(jì)數(shù)器)

????? 2、Q繼承了fork()語句執(zhí)行時(shí)當(dāng)前的環(huán)境千康,而不是程序的初始環(huán)境享幽。

????? 3、P中fork()語句啟動子進(jìn)程Q拾弃,并將Q的PID返回值桩,而Q中的fork()語句不啟動新進(jìn)程,僅將0返回豪椿。

解題

????? 下面利用上文闡述的知識進(jìn)行解題奔坟。這里我把兩個(gè)問題放在一起進(jìn)行分析胎挎。

????? 1秩铆、從shell中執(zhí)行此程序,啟動了一個(gè)進(jìn)程,我們設(shè)這個(gè)進(jìn)程為P0贴浙,設(shè)其PID為XXX(解題過程不需知道其PID)疚颊。

????? 2乡翅、當(dāng)執(zhí)行到pid1 = fork();時(shí)站宗,P0啟動一個(gè)子進(jìn)程P1,由題目知P1的PID為1001霎奢。我們暫且不管P1户誓。

????? 3、P0中的fork返回1001給pid1幕侠,繼續(xù)執(zhí)行到pid2 = fork();帝美,此時(shí)啟動另一個(gè)新進(jìn)程,設(shè)為P2晤硕,由題目知P2的PID為1002悼潭。同樣暫且不管P2。

????? 4舞箍、P0中的第二個(gè)fork返回1002給pid2舰褪,繼續(xù)執(zhí)行完后續(xù)程序,結(jié)束疏橄。所以占拍,P0的結(jié)果為“pid1:1001, pid2:1002”。

????? 5捎迫、再看P2晃酒,P2生成時(shí),P0中pid1=1001窄绒,所以P2中pid1繼承P0的1001贝次,而作為子進(jìn)程pid2=0。P2從第二個(gè)fork后開始執(zhí)行颗祝,結(jié)束后輸出“pid1:1001, pid2:0”浊闪。

????? 6、接著看P1螺戳,P1中第一條fork返回0給pid1,然后接著執(zhí)行后面的語句折汞。而后面接著的語句是pid2 = fork();執(zhí)行到這里倔幼,P1又產(chǎn)生了一個(gè)新進(jìn)程,設(shè)為P3爽待。先不管P3损同。

????? 7翩腐、P1中第二條fork將P3的PID返回給pid2,由預(yù)備知識知P3的PID為1003膏燃,所以P1的pid2=1003茂卦。P1繼續(xù)執(zhí)行后續(xù)程序,結(jié)束组哩,輸出“pid1:0, pid2:1003”等龙。

????? 8、P3作為P1的子進(jìn)程伶贰,繼承P1中pid1=0蛛砰,并且第二條fork將0返回給pid2,所以P3最后輸出“pid1:0, pid2:0”黍衙。

????? 9泥畅、至此琅翻,整個(gè)執(zhí)行過程完畢位仁。

????? 所得答案:

????? 1、一共執(zhí)行了四個(gè)進(jìn)程方椎。(P0, P1, P2, P3)

??????2障癌、另外幾個(gè)進(jìn)程的輸出分別為:

??????pid1:1001, pid2:0

????? pid1:0, pid2:1003

????? pid1:0, pid2:0

????? 進(jìn)一步可以給出一個(gè)以P0為根的進(jìn)程樹:

驗(yàn)證

????? 下面我們?nèi)inux下實(shí)際執(zhí)行這個(gè)程序,來驗(yàn)證我們的答案辩尊。

????? 程序如下圖:

????? 用gcc編譯涛浙、執(zhí)行后結(jié)果如下:

????? 由于我們不太可能剛巧碰上PID分配到1001的情況,所以具體數(shù)值可能和答案有所差別摄欲。不過將這里的2710看做基數(shù)的話轿亮,結(jié)果和我們上面的解答是一致的。

總結(jié)

????? 應(yīng)該說這不是一道特別難或特別刁鉆的題目胸墙,但是由于fork函數(shù)運(yùn)行機(jī)制的復(fù)雜性我注,造就了當(dāng)兩個(gè)fork并排時(shí),問題就變得很復(fù)雜迟隅。解這個(gè)題的關(guān)鍵但骨,一是要對linux下進(jìn)程的機(jī)制有一定認(rèn)識,二是抓住上文提到的幾個(gè)關(guān)于fork的關(guān)鍵點(diǎn)智袭。朋友說奔缠,這個(gè)題給的時(shí)間是5分鐘,應(yīng)該說時(shí)間還算充裕吼野,但是在面試的場合下校哎,還是很考驗(yàn)一個(gè)人對進(jìn)程、fork的掌握程度和現(xiàn)場推理能力。

進(jìn)程的創(chuàng)建和死亡:

闷哆,init是永遠(yuǎn)不會死亡的腰奋。看下面的linux父子進(jìn)程終止的先后順序不同產(chǎn)生不同的結(jié)果:

1)父進(jìn)程先于子進(jìn)程終止:

此種情況就是孤兒進(jìn)程抱怔。當(dāng)父進(jìn)程先退出時(shí)劣坊,系統(tǒng)會讓init進(jìn)程接管子進(jìn)程?。

2)子進(jìn)程先于父進(jìn)程終止屈留,而父進(jìn)程又沒有調(diào)用wait或waitpid函數(shù)

此種情況子進(jìn)程進(jìn)入僵死狀態(tài)局冰,且會一直保持下去直到系統(tǒng)重啟。子進(jìn)程處于僵死狀態(tài)時(shí)绕沈,內(nèi)核只保存進(jìn)程的一些必要信息以備父進(jìn)程所需锐想。此時(shí)子進(jìn)程始終占有著資源,同時(shí)也減少了系統(tǒng)可以創(chuàng)建的最大進(jìn)程數(shù)乍狐。

僵死狀態(tài):一個(gè)已經(jīng)終止赠摇、但是其父進(jìn)程尚未對其進(jìn)行善后處理(獲取終止子進(jìn)程的有關(guān)信息,釋放它仍占有的資源)的進(jìn)程被稱為僵死進(jìn)程(zombie)浅蚪。ps命令將僵死進(jìn)程的狀態(tài)打印為Z?藕帜。

3)子進(jìn)程先于父進(jìn)程終止,而父進(jìn)程調(diào)用了wait或waitpid函數(shù)?

此時(shí)父進(jìn)程會等待子進(jìn)程結(jié)束惜傲。


????? 希望本文能幫助朋友們對fork的執(zhí)行機(jī)制有一個(gè)明晰的認(rèn)識洽故。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市盗誊,隨后出現(xiàn)的幾起案子时甚,更是在濱河造成了極大的恐慌,老刑警劉巖哈踱,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荒适,死亡現(xiàn)場離奇詭異,居然都是意外死亡开镣,警方通過查閱死者的電腦和手機(jī)刀诬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來邪财,“玉大人陕壹,你說我怎么就攤上這事∈鞑海” “怎么了糠馆?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長弥奸。 經(jīng)常有香客問我榨惠,道長,這世上最難降的妖魔是什么盛霎? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任赠橙,我火速辦了婚禮,結(jié)果婚禮上愤炸,老公的妹妹穿的比我還像新娘期揪。我一直安慰自己,他們只是感情好规个,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布凤薛。 她就那樣靜靜地躺著,像睡著了一般诞仓。 火紅的嫁衣襯著肌膚如雪缤苫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天墅拭,我揣著相機(jī)與錄音活玲,去河邊找鬼。 笑死谍婉,一個(gè)胖子當(dāng)著我的面吹牛舒憾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播穗熬,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼镀迂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了唤蔗?” 一聲冷哼從身側(cè)響起探遵,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎妓柜,沒想到半個(gè)月后箱季,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡领虹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年规哪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塌衰。...
    茶點(diǎn)故事閱讀 39,932評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诉稍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出最疆,到底是詐尸還是另有隱情杯巨,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布努酸,位于F島的核電站服爷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仍源,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一心褐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧笼踩,春花似錦逗爹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至于购,卻和暖如春袍睡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背肋僧。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工斑胜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人色瘩。 一個(gè)月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓伪窖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親居兆。 傳聞我的和親對象是個(gè)殘疾皇子覆山,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 又來到了一個(gè)老生常談的問題,應(yīng)用層軟件開發(fā)的程序員要不要了解和深入學(xué)習(xí)操作系統(tǒng)呢泥栖? 今天就這個(gè)問題開始簇宽,來談?wù)劜?..
    tangsl閱讀 4,126評論 0 23
  • 1.進(jìn)程 1.1多線程的引入 現(xiàn)實(shí)生活中 有很多的場景中的事情是同時(shí)進(jìn)行的,比如開車的時(shí)候手和腳共同來駕駛汽車吧享,再...
    TENG書閱讀 500評論 0 0
  • 1魏割,ES的存儲結(jié)構(gòu)了解 在ES中,存儲結(jié)構(gòu)主要有四種钢颂,與傳統(tǒng)的關(guān)系型數(shù)據(jù)庫對比如下:index(Indices)相...
    紅薯愛帥閱讀 10,965評論 0 2
  • 剛開始我對每個(gè)出現(xiàn)在我生命中的人都報(bào)以非常高的期望钞它,希望他們能用我對他們那樣重視的態(tài)度對我。后來殊鞭,我發(fā)現(xiàn)遭垛,不是每個(gè)...
    倒立的貓閱讀 209評論 1 4
  • 《富爸爸投資指南》作者【美】羅伯特·清崎 【美】莎倫·萊希特 第一階段 你做好成為投資者的思想準(zhǔn)備了嗎? 001 ...
    青Iris閱讀 430評論 1 16