Linux程序間通訊之管道 pipe

2021-06-20 12:24:16 字數 2388 閱讀 4617

管道是unix系統ipc的最古老的形式,並且所有unix系統都提供此種通訊機制。但是管道存在如下特點:

管道是半雙工的。

管道只能用在具有公共祖先的程序之間。

管道的建立

管道是通過呼叫pipe函式建立的:

#include int pipe(int filedes[2]);
引數filedes[2]是兩個檔案描述符,filedes[0]為讀開啟,filedes[1]為寫開啟。filedes[1]的輸出是filedes[0]的輸入。

管道的實現機制

管道是由核心管理的乙個緩衝區,相當於我們放入記憶體中的乙個紙條。管道的一端連線乙個程序的輸出。

這個程序會向管道中放入資訊。管道的另一端連線乙個程序的輸入,這個程序取出被放入管道的資訊。

乙個緩衝區不需要很大,它被設計成為環形的資料結構,以便管道可以被迴圈利用。

當管道中沒有資訊的話,從管道中讀取的程序會等待,直到另一端的程序放入資訊。

當管道被放滿資訊的時候,嘗試放入資訊的程序會等待,直到另一端的程序取出資訊。當兩個程序都終結的時候,管道也自動消失。

從原理上,管道利用fork機制建立,從而讓兩個程序可以連線到同乙個pipe上。

最開始的時候,上面的兩個箭頭都連線在同乙個程序process 1上(連線在process 1上的兩個箭頭)。當fork複製程序的時候,會將這兩個連線也複製到新的程序(process 2)。

隨後,每個程序關閉自己不需要的乙個連線 (兩個黑色的箭頭被關閉; process 1關閉從pipe來的輸入連線,process 2關閉輸出到pipe的連線).

這樣,剩下的紅色連線就構成了如上圖的pipe。

管道的讀寫

寫入管道的資料按到達次序排列。如果管道滿,則對管道的寫被阻塞,直到管道的資料被讀操作讀取。

對於寫操作,如果一次write呼叫寫的資料量小於管道容量,則寫必須一次完成,

即如果管道所剩餘的容量不夠,write被阻塞直到管道的剩餘容量可以一次寫完為止。如果write呼叫寫的資料量大於管道容量,則寫操作分多次完成。

如果用fcntl設定管道寫埠為非阻塞方式,則管道滿不會阻塞寫,而只是對寫返回0。

讀操作按資料到達的順序讀取資料。已經被讀取的資料在管道內不再存在,這意味著資料在管道中不能重複利用。

如果管道為空,且管道的寫埠是開啟狀態,則讀操作被阻塞直到有資料寫入為止。

一次read呼叫,如果管道中的資料量不夠read指定的數量,則按實際的數量讀取,並對read返回實際數量值。

如果讀埠使用fcntl設定了非阻塞方式,則當管道為空時,read呼叫返回0。

如果管道的讀埠關閉,那麼在該管道上的發出寫操作呼叫的程序將接收到乙個sigpipe訊號。

關閉寫埠是給讀埠乙個檔案結束符的唯一方法。對於寫埠關閉後,在該管道上的read呼叫將返回0。

管道應用例項

管道可用於輸入輸出重定向,它將乙個命令的輸出直接定向到另乙個命令的輸入。

比如,當在某個shell程式鍵入who│wc -l後,相應shell程式將建立who以及wc兩個程序和這兩個程序間的管道。

下面的程式建立了乙個從父程序到子程序的管道。並且父程序經由管道向子程序傳送資料。

1 #include 2 #include 3 #include 4 #include 5 #include 6 

7 #define maxlen 128

8 9 int main()

10 ;

13 char buf[maxlen];

14 15 ret = pipe(filedes);

16 if (ret == -1)

20 21 ret = fork();

22 if (ret < 0) else if (ret > 0) else

38 write(stdout_fileno, buf, ret);

39 }

40 41 return 0;

42 }

程式執行結果如下:

[shenlx@centos pipe]$ ./a.out 

hello world

管道的侷限性管道的主要侷限性正體現在它的特點上:

linux程序間通訊之管道通訊

一 命名管道通訊 管道通訊分為 無名管道和有名管道 無名管道是用於父子孫程序,之間有血緣關係 有名管道 用於任意兩個程序 無名管道 1 建立 int pipe int filedis 2 它會建立兩個檔案描述符 filedis 0 用於讀管道 filedis 1 用於寫管道 通常先建立乙個管道,再通...

linux程序間通訊之管道

下面幾節,將分別溫習下linux程序進通訊的幾種機制1 管道 管道是比較古老的程序間的通訊方式。主要有有名管道和無名管道兩種。2 無名管道 它的特點就是 1 只能使用在具有親緣關係的程序之間的通訊 父子程序或者兄弟程序之間 因為只有具有親緣關係的程序才能繼承其建立的檔案描述符。2 是乙個半雙工的通訊...

Linux程序間通訊之管道

管道,你可以把它想成一根資料線,連線了兩個程序,使他們可以互相通訊。更嚴謹來說,它是乙個檔案或者一塊共享區,乙個程序往裡面寫資料,另乙個程序從裡面拿資料,以此種方式完成程序間通訊。管道是unix系統ipc最古老的形式,所有的unix系統都提供此種通訊機制 unix系統ipc是各種程序通訊方式的統稱 ...