Linux核心原始碼學習之fork的緩衝區

2021-06-26 15:47:06 字數 1871 閱讀 1344

由一道面試題引出比較好,之前寫得太亂了

會顯示幾個*?

答案是8個

【更正】圖中的一共輸出"*"個數錯了,應該是n*2^n個"*"。

後面是另乙個例子和比較亂的講解原因

不看也罷,兩個問題。

1)fork父子程序執行順序的不同導致輸出結果的不同

上面的**看上去很簡單,子子孫孫fork就是了,基本上符合我們的一般的猜想,邏輯上很正正確,但是要說的是:

為什麼同樣的**執行的時候得到的輸出會有不同?

./fork執行完成之後很正常回到了shell,但是右邊卻沒有回到shell,這是為什麼呢?

這和fork的性質【fork之後並不能確定究竟是哪個程序首先執行】相關

左邊的情況是:最後乙個程序4742執行完之後,父程序還是沒有結束的。然後父程序結束,回到父程序的父程序也就是shell

右邊的情況是:在輸出sjc@ubuntu等等之前父程序就已經執行結束退出了

所以後邊的子程序執行結束後不會回到shell,而是會回到他的父程序,不知道是誰了,反正不會是shell,所以會造成圖中所示的現象

上面說的內容不是要說的重點內容,是個人理解,不一定對,歡迎指正!

2)緩衝區繼承的問題

下面就來看看修改後的**的執**況,就和我們乍一看程式猜想或者理解上的不一致了。

同樣的**只是將列印語句的最後的'\n'換行符去掉了,執行效果確實差別很大:

列印出了16條語句!!!

這是為什麼呢?看列印語句的內容:

其中第一條肯定是最初的程序列印的,這個不會有疑問,那麼他的pid就是4772,可以看到,這個4772被列印了9次

剩下的7條分別是fork之後程序的程序pid

為什麼會列印出9條?

原來這和fork的第二條性質是相關的【fork後子程序會複製父程序的資源,緩衝區是父程序的資源,所以自然會複製乙份】

這樣就好理解了,最初的程序有7個子孫程序,所以都複製乙份一開始的緩衝區,到本身結束的時候exit會沖洗緩衝區,其中包括複製父程序的緩衝區和自己需要列印的自己的pid內容

最初的程序本身要列印兩次(一開始和最後)所以就會列印2+7*2-=16條,其中4772列印2+7=9條

既然這樣(子程序複製父程序的緩衝區),為什麼之前列印語句中帶有'\n'的實驗就能夠「正確」呢?

這是由【裝置的不同緩衝屬性】決定的。

我們現實執行結果的裝置是標準輸出裝置,而【標準輸出裝置在正常情況下是linux中的行快取的裝置(除出錯)】

'\n'正是換行符,所以會換行時清空快取。

【linux中寫入檔案流是全快取的,也就是換行符並不會沖洗緩衝區】我們讓結果輸出到檔案中會是怎樣的呢?

可以看到,不帶'\n'的輸出,除了沒有了shell的提示符外,分析還是相同的

但是帶有'\n'的輸出到檔案之後,變成了全緩衝的了,所以自然也會輸出16條語句

想必經過這個實驗,能對fork的特性和裝置的特性有乙個感性的認識了。。。。

linux核心原始碼

1.機器當前使用的核心版本 apuser jianzhangubtnb uname a linux jianzhangubtnb 3.2.0 23 generic 36 ubuntu smp tue apr 10 20 39 51 utc 2012 x86 64 x86 64 x86 64 gnu ...

Linux核心原始碼目錄

linux核心原始碼目錄 1 arch architecture的縮寫,意思是架構,九鼎在做移植的時候就刪掉了。其他的目錄都跟你沒有任何的關係,所以你完全可以把他們刪除。2 block 英文是塊的意思,表示是塊裝置。以塊 多個位元組組成的整體,以塊為單位來整體訪問 比如說我們的sd卡,inand n...

關於Linux核心原始碼使用

很多人對linux這乙個開放核心原始碼的os不會陌生,因此開源相關話題在此不再贅述。問題是,拿到了linux kernel source以後 不知道在 麼,那就看下http www.kernel.org 吧 應該如何正確的進行配置,編譯,安裝 公升級工作。事先宣告,安裝 公升級核心的操作被執行以前,...