從一道面試題分析Linux程序 IO緩衝區機制

2021-06-21 01:42:02 字數 1455 閱讀 4599

父子孫-兩次fork,2的三次方

[cpp]view plain

copy

print?

#include 

#include 

int main()  

return 0;  

}  

答案:列印出8個*,而不是6個。

分析:

如果不考慮io機制,一般可能會想,i = 0時,fork後有兩個程序,列印兩個*,i=1,時有四個程序,再列印4個*。所以一共6個。其實不是這樣的。

程序機制:

fork分叉後子程序似乎父程序的副本,子程序會複製父程序的資料空間、堆和棧。而共享**段。

c語言標準io的緩衝機制:

c語言的標準io是帶緩衝的,一般呼叫printf後,並不是立即把要列印的內容立即列印在控制台介面上,而是輸出到乙個緩衝區,對應標準輸出的叫標準輸出緩衝,對應標準出錯的叫標準出錯緩衝,當然還有標準輸入緩衝。

緩衝機制:

緩衝機制一般分為:全緩衝、行緩衝、無緩衝。

上面三種我們都能用flush和關閉檔案之類的函式強制重新整理緩衝。c語言還提供了介面讓我們改變預設的緩衝機制,以及緩衝區的大小。

回到我們的問題,根據linux程序機制,題目中的標準輸出檔案描敘符也是會被子程序複製的。所以fork後所有的程序共享乙個控制台視窗(這個解釋好像有點多餘,看不懂跳過)。io的緩衝區是用malloc申請的,是屬於堆區,所以也是子程序要從父程序複製的。那麼i= 0時,有兩個程序,他們各自輸出了乙個*,而且由於標準輸出預設採用的是行緩衝機制,所以此時,它們只是各自把乙個*複製到了標準輸出的緩衝區,沒有列印到c控制台視窗上。 接下來是關鍵時刻,接下來 i = 1,再乙個執行到fork()後,子程序複製父程序的堆區,所以後面出生的子程序也和父程序有著一樣的標準輸出緩衝區,而且標準輸出緩衝區中同樣也有著乙個*。然後執行大printf語句,所有的程序都又各自向自己的標準輸出緩衝區輸送了乙個*。  然後 i=2,程式結束了,標準輸出緩衝區的內容列印到控制台視窗上,你就看到幾個*了。

好的,我們現在統計一下。每個程序都乙個輸出了幾個*。

我們把程序按照出生的先後分為兩撥,第一波是i = 0時就出現的,包括主線程和第乙個字程序,在整個迴圈中他們向自己的標準輸出緩衝區都輸出了兩個*。

第二波是在i = 1時產生的兩個子程序,它們各自像自己的標準輸出緩衝區輸出了乙個*,但是由於它們從父程序的緩衝區裡複製了乙個*,所以它們的標準輸出緩衝區中都有兩個*。

最後程式結束,關閉標準輸出檔案時,io發生,一共向控制台視窗列印了:兩個x兩個 + 兩個x兩個 = 8個 *。

執行結果截圖:

如果把程式中的printf語句中加上乙個\n符號,改為printf("*\n"),就是下面的結果,列印出了6個*。

從一道php面試題說起

面試題目 setcookie name test echo cookies name 請說出程式結果 能說出第一次與第二次的區別者加分 本來一開始我認為不就是設定乙個cookie,然後讀出來的問題,但是被那個後面的提示搞迷惑了從來沒有想過這樣的問題。面試的時候也沒有想出答案,後來在面試官的指點下搞清...

從一道面試題開始說fork

自 http blog.csdn.net yuwenliang archive 2010 01 18 5209239.aspx 給出如下c程式,在linux下使用gcc編譯 1 include stdio.h 2 include sys types.h 3 include unistd.h 4 5 ...

一道面試題的分析

題目 console.log a var a 1 console.log a function a console.log a var a 3 console.log a function a console.log a a 執行結果 分析 題目中有多個變數宣告和函式宣告,都會提公升,而函式的優先順...