管道是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是各種程序通訊方式的統稱 ...