dup2函數參數順序配圖分析

引言: 之前在學習Linux進程間通信時,使用了管道來傳遞數據。而管道與管道之間對接採用dup2函數進行連接,發現dup2函數的兩個參數填充順序着實有趣,兩個管道之間到底是怎麼對接成功的呢?學習了一下以配圖分析的方式呈現。

一、使用場合

首先介紹這個圖: 父進程fork出一個子進程,傳遞數據給進程,希望子進程去調用一個外部程序來處理並返回數據(比如CGI程序)。
流程: 父進程fork出子進程 ——> 父進程向a[1]寫入數據 ——> 父進程等待 ——> 子進程調用外部程序 ——> 外部程序通過STDIN_FILENO拿數據(比如getchar()) ——> 外部程序執行 ——> 外部程序通過STDOUT輸出結果(比如printf()) ——> 父進程通過b[0]拿數據
這裏寫圖片描述

可以發現,圖中(1)、(2) dup2函數的參數順序,都是讀寫管道對接,到底爲什麼要這麼寫呢,這個順序是固定的嗎?需要背嗎?其實很多時候我們按照這個順序寫,卻沒有考慮爲什麼這麼寫,那麼接下來我們來闡述對接的原理。

二、瞭解文件描述符

上圖中的 STDIN_FILENO、STDOUT_FILENO, a[0]、a[1]、b[0]、b[1] 都是int型的文件描述符。所以首先我們得知道文件描述符是個什麼東西,這樣才能夠解釋管道對接的原理

下面這張圖來自百度百科,可以看到,文件描述符是是一個進程表項中的文件描述符表中的一項,它由fd標誌和文件指針構成。fd標誌:在exec後,根據標誌爲來決定該文件描述符能不能跨exec打開。文件指針:指向一個文件表,該文件表包含了該進程對文件的操作狀態、偏移量以及V節點指針。 然而V節點唯一,文件表可以多個(多個進程打開同一個文件的情況)。最後時i索引節點,i索引節點中包含了文件的所有者,文件長度,指向文件實際數據塊在磁盤上位置的指針等。
這裏寫圖片描述

也就是說,我們圖一中管道的兩端,可以進行替換來看看如下圖,管道數據傳遞實際就是兩個節點之間數據的傳遞,而調用dup2函數時,其步驟爲:1.關閉第二個參數的標誌; 2.將文件指針指向第一個參數的文件表
請注意:管道是利用內核緩衝區、環形隊列實現的,是僞文件。a[0]、a[1]指針是內核緩衝區裏的某個地方,由於父子關係,兩個進程共用這一塊內存。
這裏寫圖片描述

三、輸出重定向

原理講解差不多了,那麼我們將剛纔講解的運用一下,如何將屏幕輸出 重定向到一個文件呢?實際就是STDOUT_FILENO與某個文件描述符的dup2函數操作。

dup2(fd1, STDOUT_FILENO);

這樣就達到先關閉STDOUT_FILENO的標誌,再將其指針指向fd1的文件表,接着printf出來的數據都將被放入fd1所指向的空間,也就達到了重定向的目的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章