1. 程式人生 > >【轉】一個fork的面試題

【轉】一個fork的面試題

前兩天有人問了個關於Unix的fork()系統呼叫的面試題,這個題正好是我大約十年前找工作時某公司問我的一個題,我覺得比較有趣,寫篇文章與大家分享一下。這個題是這樣的:

題目:請問下面的程式一共輸出多少個“-”?

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
 
int main(void)
{
   int i;
   for(i=0; i<2; i++){
      fork();
      printf("-");
   }
 
   return 0;
}

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

  • fork()系統呼叫是Unix下以自身程序建立子程序的系統呼叫,一次呼叫,兩次返回,如果返回是0,則是子程序,如果返回值>0,則是父程序(返回值是子程序的pid),這是眾為周知的。
  • 還有一個很重要的東西是,在fork()的呼叫處,整個父程序空間會原模原樣地複製到子程序中,包括指令,變數值,程式呼叫棧,環境變數,緩衝區,等等。

所以,上面的那個程式為什麼會輸入8個“-”,這是因為printf(“-”);語句有buffer,所以,對於上述程式,printf(“-”);把“-”放到了快取中,並沒有真正的輸出(參看《C語言的迷題》中的第一題),在fork的時候,快取被複制到了子程序空間,所以,就多了兩個,就成了8個,而不是6個。

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

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

或是

printf("-");
fflush(stdout);

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

我估計有些朋友可能對於fork()還不是很瞭解,那麼我們把上面的程式改成下面這樣:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
   int i;
   for(i=0; i<2; i++){
      fork();
      //注意:下面的printf有“n”
      printf("ppid=%d, pid=%d, i=%d n", getppid(), getpid(), i);
   }
   sleep(10); //讓程序停留十秒,這樣我們可以用pstree檢視一下程序樹
   return 0;
}

於是,上面這段程式會輸出下面的結果,(注:編譯出的可執行的程式名為fork)

ppid=8858, pid=8518, i=0
ppid=8858, pid=8518, i=1
ppid=8518, pid=8519, i=0
ppid=8518, pid=8519, i=1
ppid=8518, pid=8520, i=1
ppid=8519, pid=8521, i=1
 
$ pstree -p | grep fork
|-bash(8858)-+-fork(8518)-+-fork(8519)---fork(8521)
|            |            `-fork(8520)

面對這樣的圖你可能還是看不懂,沒事,我好事做到底,畫個圖給你看看:

注意:上圖中的我用了幾個色彩,相同顏色的是同一個程序。於是,我們的pstree的圖示就可以成為下面這個樣子:(下圖中的顏色與上圖對應)

這樣,對於printf(“-”);這個語句,我們就可以很清楚的知道,哪個子程序複製了父程序標準輸出緩中區裡的的內容,而導致了多次輸出了。(如下圖所示,就是我陰影並雙邊框了那兩個子程序)

現在你明白了吧。(另,對於圖中的我本人拙劣的配色,請見諒!)

(全文完)

(轉載本站文章請註明作者和出處 酷殼 – CoolShell.cn ,請勿用於任何商業用途)

相關推薦

一個fork試題

前兩天有人問了個關於Unix的fork()系統呼叫的面試題,這個題正好是我大約十年前找工作時某公司問我的一個題,我覺得比較有趣,寫篇文章與大家分享一下。這個題是這樣的: 題目:請問下面的程式一共輸出多少個“-”? #include <stdio.h>#include <sys/types.h

面試iOS 開發試題(一)

readonly ava obj jce easy 主動 每一個 我不 com   1. #import 跟#include 又什麽差別,@class呢, #import<> 跟 #import””又什麽差別?   答:#import是Obje

APP界切圖命名和文件整理規範

邏輯 ner -c none 響應 小寫 感謝 父類 英文縮寫 轉自:http://www.chinaz.com/design/2015/0908/443732.shtml 規範的命名方式可以提高客戶端程序員的開發效率和團隊協作。個人覺得標識符命名原則:盡可能的用最少的字符

一個普通車民對比亞迪的評價——感覺比亞迪這兩年進步還可以,果斷轉載了

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

本人禿頂程式設計師一個畢業6年的程式設計師工作經歷和成長感悟

←←←←←←←←←←←← 我都禿頂了,還不點關注! 【本人禿頂程式設計師】轉自今日頭條:Java高階 原文連結:https://www.toutiao.com/i6611344590853112324/ 把時鐘撥回到2007年的夏天,大學畢業。那時非常迷茫,不知道自己能做什麼,想做什

SQL常用MySQL試題(二)

SQL索引 一、為什麼要建立索引呢(優點)? 建立索引可以大大提高系統的效能。 第一, 通過建立唯一性索引,可以保證資料庫表中每一行資料的唯一性。 第二, 可以大大加快資料的檢索速度,這也是建立索引的最主要的原因。 第三, 可以加速表和表之

SQL常用MySQL試題(一)

1、資料庫事務的四個特性及含義 資料庫事務transanction正確執行的四個基本要素。ACID,原子性(Atomicity)、一致性(Correspondence)、隔離性(Isolation)、永續性(Durability)。 原子性:整

原創python處理 試題:迴文…

今日面試題:迴文分割 對一個字串按照迴文進行分割,例如aba|b|bbabb|a|b|aba就是字串ababbbabbababa的一個迴文分割,每一個字串都是一個迴文。請找到可以分割的最少的字串數。例如: ababbbabbababa最少4個字串,分割三次:a|babbbab|b|ababa

一個易錯的試題來加深對C++多型的理解

    原題目程式比較長, 我來簡化成核心的考察部分, 如下: #include <iostream> using namespace std; class A { public: virtual void x() { cout <<

典型的JavaScript試題

() cee not spa tro cnblogs and enc 分配 問題1: 作用域(Scope) 1 (function() { 2 "use strict"; 3 var a = b = 5; 4 })(); 5 console.log(b); 控

從一道試題來認識java類加載時機與過程

包含 布局 hello 印象 大致 周期 default () itl 說明:本文的內容是看了《深入理解Java虛擬機:JVM高級特性與最佳實踐》後為加印象和理解,便記錄了重要的內容。 1 開門見山 以前曾經看到過一個java的面試題,當時覺得此題很簡單,可是自己

前端小小白的學習之路整理幾道試題之(HTTP協議)

ase 賬號 檢測 提交數據 大型數據集 tor 添加 描述 分享 轉自:http://www.cnblogs.com/ranyonsue/p/5984001.html HTTP簡介 HTTP協議是Hyper Text Transfer Protocol(超文本傳輸

在linux程序裏,知道一個函數地址,改函數是屬於某個動態庫的,怎麽樣得到這個動態庫的全

main 動態庫 360doc 復制 address 函數 地址 ati content 轉自:http://www.360doc.com/content/17/1012/11/48326749_694292472.shtml 另外dl_iterate_phdr可以查到當

樂視mysql試題

需要 好的 硬件 select 業務 以及 局限性 測試環境 獨立 最近,朋友去樂視面試了mysql DBA,以下是我據整理的樂視mysql面試題答案,供大家參考 1. MYISAM和INNODB的不同?答:主要有以下幾點區別: a)構造上的區別 MyISAM

Python試題(二)

www. toolbar code 很大的 fin alt log 表達 字符 轉載出處http://www.cnblogs.com/goodhacker/p/3387027.html 1.python中類方法、類實例方法、靜態方法有何區別? 區別: 類方法和靜態方法都

漫畫:經典谷歌試題“扔雞蛋”,看看你會做嗎?

 第二天 題目:扔雞蛋問題 有2個雞蛋,從100層樓上往下扔,以此來測試雞蛋的硬度。比如雞蛋在第9層沒有摔碎,在第10層摔碎了,那

有趣的積水問題(Twitter程式設計試題)

以下內容來自轉載: Twitter面試題:水溝積水問題 問題描述:“看下面這個圖片” “在這個圖片裡我們有不同高度的牆。這個圖片由一個整數陣列所代表,陣列中每個數是牆的高度。上邊的圖可以表示為陣列[2,5,1,2,3,4,7,7,6]” “假如開始下雨了,那麼

Java Collection(集合)必考試題

Arraylist 與 LinkedList 異同 1. 是否保證執行緒安全: ArrayList 和 LinkedList 都是不同步的,也就是不保證執行緒安全; 2. 底層資料結構: Arraylist 底層使用的是Object陣列;LinkedList 底層使用的是雙

NIOJava面試高階篇—Java NIO:淺析I/O模型試題15期

在進入Java NIO程式設計之前,我們今天先來討論一些比較基礎的知識:I/O模型。本文先從同步和非同步的概念 說起,然後接著闡述了阻塞和非阻塞的區別,接著介紹了阻塞IO和非阻塞IO的區別,然後介紹了同步IO和非同步IO的區別,接下來介紹了5種IO模型,最後介紹了兩種和高

SQL今天的一個sql試題(分組函式使用)

已經對試題做了化名處理。 表記錄如下: 根據表記錄,利用sql得出如下的結果: 這裡之所以記錄下來,是因為這個sql必須要用到高階分析函式,就是分組內排序和分組求和。 意思就是,題目要求就是按照deptno來分組,然後在分組內將記錄按照sal來排序,並且求得每條記錄