幾個fork面試題目的驗證

2021-06-14 06:34:54 字數 2361 閱讀 8879

第一題,計算下面**理論上總共列印了多少行:(網易2011筆試題)

int 

main()

}

問題解答:

問題的答案為62,基本方法為2+4+8+16+32=62,可以認為是每次程序數目加倍,輸出的數目實際對應程序的數目,另外原文提出了另一種解決此問題的方法,可以參考原文。

但是如果用程式驗證,就不可能得到正確的答案,所以在題目中說明是「理論上「。因為在主程序結束之前,子程序並不一定能夠完成執行,為了保證子程序的順利結束,應當在每乙個fork()之後增加wait(),等待子程序結束。驗證程式**如下,

int 

main()

}

可以發現最後輸出預期的62行,而且可以通過統計最後的child為-1的值,得到產生的子程序的總數目。因為第一次產生子程序時候,子程序執行到此會因為沒有子程序而返回-1錯誤,可以用perror()檢視錯誤原因為」no child processes"。

第二題:問下面的**執行後總共產生了多少程序(不包括主程序)?(2009 emc筆試)

#include

int main()

題目的解法在原文中可以得到,這裡列出基本解決方法,驗證才是本文重點。

題目考察兩方面的知識:1、fork()返回值;2、&&和||的運算。

&&是「邏輯與」操作,如果兩個運算元有乙個為0,則整個式子為0。標準c中規定,如果&&運算子的左運算元為0,則不計算右運算元;如果左運算元為1,才計算右運算元。與之類似,||操作符是「邏輯或」操作,標準c規定如果||運算子左運算元為1,則不計算右運算元;如果左運算元為0,則計算右運算元。

繼續來看我們的題目,我們把題目中的5個fork()分別標記為a,b,c,d,e。則我們可以看到,主程序一共產生4個程序,分別產生在a,b,c,e位置上(b,c兩個fork()返回值都不是0,因此b&&c不為0,因此不計算d)。

因為同樣的原因看,用程式無法直接得到程序數目。而且此處不像上乙個題目一樣能夠在fork()之後增加wait()操作。我們仍然採用增加wait()操作的方法,方法為對fork()函式進行包裹,函式的形參與返回值與原函式相同,不過在中間增加wait()。如此可以保證子程序順利結束。而且在程式的最後增加乙個輸出操作,輸出的操作符數目即是程序總數目,但是記住輸出一定要使用換行符"\n"或者清空緩衝區,否則最後的輸出符號數目並不是程序的總數目,此處將在第三題說明。**如下:

int main(int argc, char** argv)

pid_t fork()

最終的輸出結果為20,除去主程序,產生了19個子程序。

#include #include #include intmain(void)

return0;

}

分析fork()的機制比較熟悉的話,這個題並不難,輸出應該是6個「-」,但是,實際上這個程式會很tricky地輸出8個「-」。

要講清這個題,我們首先需要知道fork()系統呼叫的特性

(1) fork()系統呼叫是unix下以自身程序建立子程序的系統呼叫,一次呼叫,兩次返回,如果返回是0,則是子程序,如果返回值》0,則是父程序(返回值是子程序的pid),這是眾為周知的。

(2) 還有乙個很重要的東西是,在fork()的呼叫處,整個父程序空間會原模原樣地複製到子程序中,包括指令,變數值,程式呼叫棧,環境變數,緩衝區,等等。

所以,上面的那個程式為什麼會輸入8個「-」,這是因為printf(「-」);語句有buffer,所以,對於上述程式,printf(「-」);把「-」放到了快取中,並沒有真正的輸出,在fork的時候,快取被複製到了子程序空間,所以,就多了兩個,就成了8個,而不是6個。

另外,多說一下,我們知道,unix下的裝置有「塊裝置」和「字元裝置」的概念,所謂塊裝置,就是以一塊一塊的資料訪問的裝置,字元裝置是一次訪問乙個字元的裝置。磁碟、記憶體都是塊裝置,字元裝置如鍵盤和串列埠。塊裝置一般都有快取,而字元裝置一般都沒有快取。

對於上面的問題,我們如果修改一下上面的printf的那條語句為:

printf("-");

fflush(stdout);

或者

printf("-\n");

就沒有問題了(就是6個「-」了),因為程式遇到「\n」,或是eof,或是緩中區滿,或是檔案描述符關閉,或是主動flush,或是程式退出,就會把資料刷出緩衝區。需要注意的是,標準輸出是行緩衝,所以遇到「\n」的時候會刷出緩衝區,但對於磁碟這個塊裝置來說,「\n」並不會引起緩衝區刷出的動作,那是全緩衝,你可以使用setvbuf來設定緩衝區大小,或是用fflush刷快取。

幾個Linux驅動面試題目

這幾天面試幾個想做安卓linux驅動的,總體感覺上驅動基礎還是比較薄弱,大部分情況是雖然做過驅動,但是基本上都是採用核心現成的,或者是開發板上已經有的,單獨寫過模組驅動很少,驅動機制理解不是很透徹.以下是幾個隨口問過的基礎問題,供參考.1 字元型驅動裝置你是怎麼建立裝置檔案的,就是 dev 下面的裝...

fork的面試題

一 fork入門知識 乙個程序,包括 資料和分配給程序的資源。fork 函式通過系統呼叫建立乙個與原來程序幾乎完全相同的程序,也就是兩個程序可以做完全相同的事。但如果初始引數或者傳入的變數不同,兩個程序也可以做不同的事。乙個程序呼叫fork 函式後,系統先給新的程序分配資源,例如儲存資料和 的空間。...

幾個面試題

1 公司裡面有1001個員工,現在要在公司裡面找到最好的羽毛球選手,也就是第一名,每個人都必須參賽,問至少要比賽多少次才能夠找到最好的羽毛球員工 2 現在有100個燈泡,每個燈泡都是關著的,第一趟把所有的燈泡燈泡開啟,第二趟把偶數字的燈泡制反 也就是開了的關掉,關了的開啟 第三趟讓第3,6,9.的燈...