程序間通訊 管道(匿名與命名)

2021-08-18 17:39:21 字數 2523 閱讀 5458

從物理上分,可以將管道分為同主機的程序之間的通訊和不同主機間的程序之間的通訊。從通訊方式上來分,管道又分為匿名管道和命名管道,下面就匿名管道和命名管道的特性作以闡述。

[含義]:管道是乙個程序的資料流到另乙個程序的通道,即乙個程序的資料的輸出作為另乙個程序的資料的輸入,管道起到橋梁作用。

比如:當我們輸入:ls -l | cat test 其中的 ls 和 cat 是兩個程序, | 代表管道,意思是執行 ls -l 程序,並將輸出結果作為cat test 程序的輸入,cat 程序將輸入的結果列印在螢幕上。

[本質]:匿名管道之所以可以通訊的本質在於,父程序frok子程序,父子程序各自擁有乙個檔案描述符表,但是兩者的內容是一樣的,既然內容一樣,那麼指向的就是同乙個管道,即父子程序看到了同乙份公共資源。

[管道的建立]:管道是一種最基本的ipc機制,由pipe函式建立:

int pipe(fd[2]);

fd :檔案描述符陣列

fd[2]:表示管道的輸入輸出端,輸出端資料經過管道流到輸入端,函式執行完後,會將這個陣列賦值。

fd[0]:表示管道輸入端的檔案描述符。

fd[1]:表示管道輸出端的檔案描述符。

[程序間通訊示意圖]:我們讓父程序關閉管道讀端,子程序關閉管道寫端。父程序可以給管道裡面寫,子程序可以從管道裡面讀,管道是用環形佇列實現的,資料從寫端流入從讀端流出,這樣就實現了程序間通訊。

使用管道是有一些限制的,兩個程序通過乙個管道只能實現單向通訊。比如上述例子,父程序寫,子程序讀,如果需要子程序寫,父程序讀,就必須另開乙個管道。

[管道的五大特性]:

(1)匿名管道只能單向通訊。

(2)管道只能進行在有血緣關係的程序間通訊,通常用於父子程序。

(3)管道通訊依賴於檔案系統,即管道的生命週期隨程序。

(4)管道的通訊被稱為面向位元組流,與通訊格式沒有關係。

(5)管道自帶同步機制,保證讀寫順序一致。

[思考題]:如果只開乙個管道,但是父程序不關閉讀端,子程序不關閉寫端,雙方都保留讀寫端,為什麼不能實現雙向通訊?

解析:管道的讀寫端是通過開啟的檔案描述符來傳遞的,因此要通訊的兩個程序必須從他們的公共祖先那裡繼承管道的檔案描述符。

[匿名管道的四種特殊情況]:假設都是阻塞i/o操作,沒有設定o_nonblock標誌。

(1)如果所有指定管道寫端的檔案描述符都關閉了(管道寫端的引用計數為0),而仍然有程序從管道的讀端讀資料,那麼管道中剩餘的資料被讀取後,再次read會返回0,就像讀到檔案末尾一樣。

(2)如果有指向管道寫端的檔案描述符沒有關閉(管道寫端的引用計數大於0),而持有寫端的程序也沒有向管道中寫資料,這時有程序從管道讀端讀資料,那麼管道中剩餘的資料被讀取後,再次read會阻塞,直到管道中有資料可讀了才讀取資料並返回。

(3)如果所有指向管道讀端的檔案描述符都關閉了(管道讀端的引用計數等於0),這時有程序向管道寫端write,那麼該程序會收到訊號sigpipe,通常會導致程序異常終止。

(4)如果有指向管道讀端的檔案描述符沒有關閉(管道讀端的引用計數大於0),而持有管道讀端的程序也沒有從管道中讀取資料,這時有程序向管道的寫端寫入資料,那麼管道被寫滿時,再次 write 會阻塞,直到管道中有空位置了才寫入資料並返回。

[本質]:命名管道在某種程度上可以看做是匿名管道,但它打破了匿名管道只能在有血緣關係的程序間的通訊。命名管道之所以可以實現程序間通訊在於通過同乙個路徑名而看到同乙份資源,這份資源以fifo的檔案形式存於檔案系統中。

值得注意的是,fifo總是按照先入先出的原則工作,第乙個被寫入的資料將首先從管道讀出。

[管道的建立]:我們可以使用下列函式之一來建立命名管道。

int mkfifo(const char* filename,mode_t mode);

int mknod(const char* filename,mode_t mode,dev_t dev);

這兩個函式都可以建立乙個fifo檔案,注意是建立乙個真實存在於檔案系統的檔案。

[filename]:指定了檔名。

[mode]:指定了檔案的讀寫許可權。

mknod是比較老的函式,而mkfifo函式更加簡單和規範,所以建議在可能情況下,盡量使用mkfifo。

[作用]:在檔案系統中建立乙個檔案,該檔案用於提供fifo功能,即命名管道。對檔案系統來說,匿名管道是不可見的,它的作用僅限於在父程序與子程序之間的通訊。而命名管道是乙個可見的檔案,因此,它可以用於任何兩個程序之間的通訊。

程序間通訊 管道 命名管道 FIFO

比較類似程序間的生產者 消費者模型。乙個程序向管道中寫入資料,另乙個程序從管道中讀出資料。pipe為無名管道,提供的是一組半雙工通訊方式。pipe會建立兩個檔案物件,乙個索引節點。pipe在核心中會有乙個快取,快取大小可能若干個頁大小。呼叫write像管道裡寫資料時,系統會將資料存於快取,另乙個執行...

程序間通訊 管道

include int pipe int fd 2 返回值 若成功,返回0,若出錯,返回 1經由引數fd返回兩個檔案描述符 fd 0 為讀而開啟,fd 1 為寫而開啟。fd 1 的輸出是fd 0 的輸入。else if pid 0 子程序 else else if pid 0 父程序 printf ...

程序間通訊 管道

原文 程序間通訊 管道 管道簡介 常說的管道都是匿名半雙工管道,匿名半雙工管道在系統中是沒有實名的,並不可以在檔案系統中以任何方式看到該管道。它只是程序的一種資源,會隨著程序的結束而被系統清除。管道通訊是在unix系統中應用比較頻繁的一種方式,例如使用grep查詢 ls grep ipc 顧名思義,...