by:
潘雲登
對於商業目的下對本文的任何行為需經作者同意。
寫在前面
1.本文內容對應《
unix
環境高階程式設計》(第
2版)》第
15章。 2.
總結了程序間通訊的一種機
制——管道的基本概念和使用方法。 3.
管道
管道是unix
系統ipc
的最古老形式,在
shell
下的表現形式為管道線。每當在管道線中輸入乙個由
shell
執行的命令序列時,
shell
為每一條命令單獨建立一程序,然後將前一條命令程序的標準輸出用管道與後一條命令的標準輸入相連線。管道有兩個主要侷限: l
管道是半雙工的,即資料只能在乙個方向上流動。 l
管道只能在具有公共祖先的程序之間使用。
管道的建立
管道由pipe
函式建立。經由引數
filedes
返回兩個檔案描述符:
filedes[0]
為讀而開啟,
filedes[1]
為寫而開啟(讀0寫
1)。filedes[1]
的輸出是
filedes[0]
的輸入。
fstat
函式對管道的每一端都返回乙個
fifo
型別的檔案描述符,可以用
s_isfifo
巨集來測試管道。
#include
int pipe(int filedes[2]);
returns: 0 if ok, -1 on error
單個程序中的管道幾乎沒有任何用處。通常,呼叫
pipe
函式的程序接著呼叫
fork
,這樣就建立了從父程序到子程序(或反向)的
ipc通道。對於從父程序到子程序的管道,父程序關閉管道的讀端,子程序則關閉寫端。對於反向的管道,父程序關閉寫端,子程序則關閉讀端。
讀寫管道
可以直接呼叫
read
和write
對管道描述符進行讀寫。更常見的方法是將管道描述符複製為標準輸入和標準輸出。在此之後,子程序通常執行另乙個程式,該程式或者從標準輸入(管道的讀端)讀資料,或者將資料寫到其標準輸出(管道的寫端)。
在寫管道時,常量
pipe_buf
規定了核心中管道緩衝區的大小。如果有多個程序同時寫乙個管道,而且有程序要求寫的位元組數超過
pipe_buf
位元組數時,則寫操作的資料可能互相穿插。用
pathconf
或fpathconf
函式可以確定
pipe_buf
的值。
當管道的一端被關閉後,下列的兩條規則起作用: l
當讀乙個寫端已被關閉的管道時,在所有資料都被讀取後,
read返回0
,以指示達到了檔案結尾處。 l
如果寫乙個讀端已被關閉的管道,則產生訊號
sigpipe
。如果忽略該訊號或者捕捉該訊號並從其訊號處理函式返回,則
write
返回-1
,errno
設定為epipe。
實驗程式如下:
#include
#include
#include
#include
#include
void sig_pipe(int signo)
int main()
if((pid = fork()) < 0)
else if(pid == 0)
close(fd[0]);
sleep(1);
if(write(fd[1], buf, 10) == -1)
perror("write error");
exit(exit_success); }
執行結果為:
pydeng@pydeng-laptop:~/apue.2e/mytest$ ./a.out
receive sigpipe
write error: broken pipe
協同程序
當乙個程式產生某個過濾程式的輸入,同時又讀取該過濾程式的輸出時,則該過濾程式就成為協同程序。協同程序通常在
shell
的後台執行,它有連線到另乙個程序的兩個單向管道,乙個接到其標準輸入,另乙個則來自其標準輸出。
APUE筆記 程序間通訊
管道 include int pipe int fds 2 fd返回兩個檔案描述符,fd 0 讀,fd 1 寫!管道是單雙工的,只能一端寫,另一端讀,不能兩邊同時讀寫 管道實際上是在,核心中開闢了乙個迴圈佇列,當佇列寫滿 隊空 時,繼續寫 讀 管道會阻塞當前程序!當寫端關閉,繼續讀時返回eof 當讀...
APUE 程序間通訊
現在,某些系統提供全雙工管道,但是為了最佳的可移植性,我們決不應預先假定系統支援全雙工管道。管道只能在具有公共祖先的兩個程序之間使用。通常,乙個管道由乙個程序建立,在程序呼叫fork之後,這個管道就能在父程序和子程序之間使用了。每當在管道中鍵入乙個命令序列,讓shell執行時,shell都會為每一條...
APUE筆記 高階程序間通訊
unix 域套接字 unix域套接字,使用socket相同的介面,用於程序間通訊 但它僅僅進行資料複製,不新增報頭,不計算校驗和 unix域套接字,在系統中建立兩個檔案,檔案不實際儲存資料,指向核心空間中相應位址 使用socketpair建立乙個類似於管道的socketfd fd 2 不同於管道,此...