成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

從一道面試題談Linux下fork的運行機制

系統 Linux
一個不錯的外企面試Linux開發職位,應該說不是一道特別難或特別刁鉆的題目,但是由于fork函數運行機制的復雜性,造就了當兩個fork并排時,問題就變得很復雜。解這個題的關鍵,一是要對linux下進程的機制有一定認識,二是抓住上文提到的幾個關于fork的關鍵點。

[[227280]]

一個不錯的外企面試Linux開發職位,面試官出了一個如下的題目:

從一道面試題談Linux下fork的運行機制

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

已知從這個程序執行到這個程序的所有進程結束這個時間段內,沒有其它新進程執行。

  1. 請說出執行這個程序后,將一共運行幾個進程。
  2. 如果其中一個進程的輸出結果是“pid1:1001, pid2:1002”,寫出其他進程的輸出結果(不考慮進程執行順序)。

明顯這道題的目的是考察linux下fork的執行機制。下面我們通過分析這個題目,談談Linux下fork的運行機制。

預備知識:

這里先列出一些必要的預備知識,對Linux下進程機制比較熟悉的朋友可以略過。

  1. 進程可以看做程序的一次執行過程。在Linux下,每個進程有唯一的PID標識進程。PID是一個從1到32768的正整數,其中1一般是特殊進程init,其它進程從2開始依次編號。當用完32768后,從2重新開始。
  2. Linux中有一個叫進程表的結構用來存儲當前正在運行的進程??梢允褂?ldquo;ps aux”命令查看所有正在運行的進程。
  3. 進程在Linux中呈樹狀結構,init為根節點,其它進程均有父進程,某進程的父進程就是啟動這個進程的進程,這個進程叫做父進程的子進程。
  4. fork的作用是復制一個與當前進程一樣的進程。新進程的所有數據(變量、環境變量、程序計數器等)數值都和原進程一致,但是是一個全新的進程,并作為原進程的子進程。

解題的關鍵:

有了上面的預備知識,我們再來看看解題的關鍵。我認為,解題的關鍵就是要認識到fork將程序切成兩段。看下圖:

從一道面試題談Linux下fork的運行機制

上圖表示一個含有fork的程序,而fork語句可以看成將程序切為A、B兩個部分。然后整個程序會如下運行:

  • step1、設由shell直接執行程序,生成了進程P。P執行完Part. A的所有代碼。
  • step2、當執行到pid = fork();時,P啟動一個進程Q,Q是P的子進程,和P是同一個程序的進程。Q繼承P的所有變量、環境變量、程序計數器的當前值。
  • step3、在P進程中,fork()將Q的PID返回給變量pid,并繼續執行Part. B的代碼。
  • step4、在進程Q中,將0賦給pid,并繼續執行Part. B的代碼。

這里有三個點非常關鍵:

  1. P執行了所有程序,而Q只執行了Part. B,即fork()后面的程序。(這是因為Q繼承了P的PC-程序計數器)
  2. Q繼承了fork()語句執行時當前的環境,而不是程序的初始環境。
  3. P中fork()語句啟動子進程Q,并將Q的PID返回,而Q中的fork()語句不啟動新進程,僅將0返回。

解題:

下面利用上文闡述的知識進行解題。這里我把兩個問題放在一起進行分析。

  1. 從shell中執行此程序,啟動了一個進程,我們設這個進程為P0,設其PID為XXX(解題過程不需知道其PID)。
  2. 當執行到pid1 = fork();時,P0啟動一個子進程P1,由題目知P1的PID為1001。我們暫且不管P1。
  3. P0中的fork返回1001給pid1,繼續執行到pid2 = fork();,此時啟動另一個新進程,設為P2,由題目知P2的PID為1002。同樣暫且不管P2。
  4. P0中的第二個fork返回1002給pid2,繼續執行完后續程序,結束。所以,P0的結果為“pid1:1001, pid2:1002”。
  5. 再看P2,P2生成時,P0中pid1=1001,所以P2中pid1繼承P0的1001,而作為子進程pid2=0。P2從第二個fork后開始執行,結束后輸出“pid1:1001, pid2:0”。
  6. 接著看P1,P1中***條fork返回0給pid1,然后接著執行后面的語句。而后面接著的語句是pid2 = fork();執行到這里,P1又產生了一個新進程,設為P3。先不管P3。
  7. P1中第二條fork將P3的PID返回給pid2,由預備知識知P3的PID為1003,所以P1的pid2=1003。P1繼續執行后續程序,結束,輸出“pid1:0, pid2:1003”。
  8. P3作為P1的子進程,繼承P1中pid1=0,并且第二條fork將0返回給pid2,所以P3***輸出“pid1:0, pid2:0”。
  9. 至此,整個執行過程完畢。

所得答案:

1、一共執行了四個進程。

  1. (P0, P1, P2, P3) 

2、另外幾個進程的輸出分別為:

 

  1. pid1:1001, pid2:0  
  2. pid1:0, pid2:1003  
  3. pid1:0, pid2:0 

進一步可以給出一個以P0為根的進程樹:

從一道面試題談Linux下fork的運行機制

驗證:

下面我們去linux下實際執行這個程序,來驗證我們的答案。

程序如下圖:

從一道面試題談Linux下fork的運行機制

用gcc編譯、執行后結果如下:

從一道面試題談Linux下fork的運行機制

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

總結:

應該說這不是一道特別難或特別刁鉆的題目,但是由于fork函數運行機制的復雜性,造就了當兩個fork并排時,問題就變得很復雜。解這個題的關鍵,一是要對linux下進程的機制有一定認識,二是抓住上文提到的幾個關于fork的關鍵點。朋友說,這個題給的時間是5分鐘,應該說時間還算充裕,但是在面試的場合下,還是很考驗一個人對進程、fork的掌握程度和現場推理能力。

責任編輯:未麗燕 來源: Linux云計算數據自學
相關推薦

2021-03-27 10:59:45

JavaScript開發代碼

2024-10-11 17:09:27

2021-04-13 08:50:21

JS作用域面試題

2011-05-23 11:27:32

面試題面試java

2018-03-06 15:30:47

Java面試題

2023-02-04 18:24:10

SeataJava業務

2009-08-11 10:12:07

C#算法

2009-08-11 14:59:57

一道面試題C#算法

2017-11-21 12:15:27

數據庫面試題SQL

2022-04-08 07:52:17

CSS面試題HTML

2009-08-11 15:09:44

一道面試題C#算法

2021-05-31 07:55:44

smartRepeatJavaScript函數

2023-08-01 08:10:46

內存緩存

2021-10-28 11:40:58

回文鏈表面試題數據結構

2021-03-16 05:44:26

JVM面試題運行時數據

2022-02-08 18:09:20

JS引擎解析器

2015-09-02 14:09:19

面試題程序設計

2017-03-10 09:33:16

JavaScript類型

2011-03-02 10:58:16

SQL server入門面試題

2017-09-13 07:15:10

Python讀寫文件函數
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美色人| 成人欧美 | 国产国产精品久久久久 | 成人中文字幕av | 日韩中文字幕一区二区三区 | 欧美爱爱视频网站 | 日韩av一区二区在线观看 | 国产97在线 | 日韩 | 亚洲va在线va天堂va狼色在线 | 亚洲a在线视频 | www亚洲一区 | 久草.com| 99自拍视频 | 日韩高清不卡 | 亚洲一区二区在线视频 | 成人片免费看 | 日日夜夜av | 久久精品国产99国产精品 | 日韩在线三级 | 亚洲国产成人精品一区二区 | 91精品国产一区二区三区 | av永久 | 国产偷自视频区视频 | 四虎影视| 久久国产福利 | 成人av大全 | 九九av| 国产三级精品三级在线观看四季网 | 国产精品久久av | 精品久久久久久久久久久久久久 | 日韩国产中文字幕 | 久久91精品| 亚洲最大的黄色网址 | 成人免费视频观看 | 日韩黄色av | 成人午夜高清 | 剑来高清在线观看 | 久草www| 农村真人裸体丰满少妇毛片 | www日韩欧美 | 成人黄色在线视频 |