linux 管道學習

2021-06-16 09:53:06 字數 2040 閱讀 9413

管道是linux中很重要的一種通訊方式,是把乙個程式的輸出直接連線到另乙個程式的輸入,常說的管道多是指無名管道,無名管道只能用於具有親緣關係的程序之間,這是它與有名管道的最大區別。

有名管道叫named pipe或者fifo(先進先出),可以用函式mkfifo()建立。

linux管道的實現機制

在linux中,管道是一種使用非常頻繁的通訊機制。從本質上說,管道也是一種檔案,但它又和一般的檔案有所不同,管道可以克服使用檔案進行通訊的兩個問題,具體表現為:

· 限制管道的大小。實際上,管道是乙個固定大小的緩衝區。在linux中,該緩衝區的大小為1頁,即4k位元組,使得它的大小不象檔案那樣不加檢驗地增長。使 用單個固定緩衝區也會帶來問題,比如在寫管道時可能變滿,當這種情況發生時,隨後對管道的write()呼叫將預設地被阻塞,等待某些資料被讀取,以便騰 出足夠的空間供write()呼叫寫。

· 讀取程序也可能工作得比寫程序快。當所有當前程序資料已被讀取時,管道變空。當這種情況發生時,乙個隨後的read()呼叫將預設地被阻塞,等待某些資料被寫入,這解決了read()呼叫返回檔案結束的問題。

注意:從管道讀資料是一次性操作,資料一旦被讀,它就從管道中被拋棄,釋放空間以便寫更多的資料。

1. 管道的結構

在 linux 中,管道的實現並沒有使用專門的資料結構,而是借助了檔案系統的file結構和vfs的索引節點inode。通過將兩個 file 結構指向同乙個臨時的 vfs 索引節點,而這個 vfs 索引節點又指向乙個物理頁面而實現的。

2.管道的讀寫

管道實現的源**在fs/pipe.c中,在pipe.c中有很多函式,其中有兩個函式比較重要,即管道讀函式pipe_read()和管道寫函式 pipe_wrtie()。管道寫函式通過將位元組複製到 vfs 索引節點指向的物理記憶體而寫入資料,而管道讀函式則通過複製物理記憶體中的位元組而讀出資料。當然,核心必須利用一定的機制同步對管道的訪問,為此,核心使用 了鎖、等待佇列和訊號。

當寫程序向管道中寫入時,它利用標準的庫函式write(),系統根據庫函式傳遞的檔案描述符,可找到該檔案的 file 結構。file 結構中指定了用來進行寫操作的函式(即寫入函式)位址,於是,核心呼叫該函式完成寫操作。寫入函式在向記憶體中寫入資料之前,必須首先檢查 vfs 索引節點中的資訊,同時滿足如下條件時,才能進行實際的記憶體複製工作:

·記憶體中有足夠的空間可容納所有要寫入的資料; 

·記憶體沒有被讀程式鎖定。 

如 果同時滿足上述條件,寫入函式首先鎖定記憶體,然後從寫程序的位址空間中複製資料到記憶體。否則,寫入程序就休眠在 vfs 索引節點的等待佇列中,接下來,核心將呼叫排程程式,而排程程式會選擇其他程序執行。寫入程序實際處於可中斷的等待狀態,當記憶體中有足夠的空間可以容納寫 入資料,或記憶體被解鎖時,讀取程序會喚醒寫入程序,這時,寫入程序將接收到訊號。當資料寫入記憶體之後,記憶體被解鎖,而所有休眠在索引節點的讀取程序會被喚 醒。

管道的讀取過程和寫入過程類似。但是,程序可以在沒有資料或記憶體被鎖定時立即返回錯誤資訊,而不是阻塞該程序,這依賴於檔案或管道的開啟模式。反之,程序 可以休眠在索引節點的等待佇列中等待寫入程序寫入資料。當所有的程序完成了管道操作之後,管道的索引節點被丟棄,而共享資料頁也被釋放。

因為管道的實現涉及很多檔案的操作,因此,當讀者學完有關檔案系統的內容後來讀pipe.c中的**,你會覺得並不難理解。

linux 管道的建立和使用都要簡單一些,唯一的原因是它需要更少的引數。實現與 windows 相同的管道建立目標,linux 和 unix 使用下面的**片段:

建立 linux 命名管道

int fd1[2];

if(pipe(fd1)) 

linux 管道對阻塞之前一次寫操作的大小有限制。 專門為每個管道所使用的核心級緩衝區確切為 4096 位元組。 除非閱讀器清空管道,否則一次超過 4k 的寫操作將被阻塞。 實際上這算不上什麼限制,因為讀和寫操作是在不同的執行緒中實現的。

linux 管道比 windows 2000 命名管道快很多,而 windows 2000 命名管道比 windows xp 命名管道快得多。

例子:#include

#include

int main()

else

exit(0);

}

shell管道學習

在shell指令碼中呼叫另乙個指令碼的三種不同方法 fork directory script.sh 如果shell中包含執行命令,那麼子命令並不影響父級的命令。在子命令執行完後再執行父級命令,子級的環境變數不會影響到父級。fork是最普通的,就是直接在指令碼裡面用 directory script...

程序間通訊 管道學習筆記

均為整理的資料,侵刪 ipc的通訊方式 管道.管道一般分為匿名管道和有名管道.管道是最基本的程序通訊的方式.匿名管道特點只能在父子程序之間進行使用.有名管道客戶克服管道沒有名字的限制 因此,除了具有管道所具有的功能之外,還允許無親緣關係程序之間的通訊 匿名管道 pipe 特徵 要實現管道,我們首先介...

Linux學習 管道

正在學習linux,記錄一下學習歷程。管道線乙個程式的標準輸出可以自動傳送給下乙個命令的標準輸入。兩個程式之間的連線就是管道 pipe 在建立管道線時,將命令用 豎線 分隔開。並且命令必須為過濾器。過濾器 能夠從標準輸入讀取文字,並向標準輸出寫入文字的程式。管道示例 ls l afile bfile...