1.管道的定義
當從乙個連線資料流到另乙個程序時,我們使用術語管道(pipe)。對於shell命令來說,命令的連線是通過管道字元來完成的,如下所示:
cmd1 | cmd2
shell負責安排兩個命令的標準輸入和標準輸出。
cmd1的標準輸入來自終端鍵盤。
cmd1的標準輸出傳遞給cmd2,作為它的標準輸入。
cmd2的標準輸出連線到終端螢幕。
shell所做的工作實際上是針對標準輸入和標準輸出流進行了重新連線。
2.程序管道
最簡單的在兩個程式之間傳遞資料的方法就是使用popen和pclose函式。
#include
file *popen(const char *command, const char *open_mode);
int pclose(file *stream_to_close);
popen函式:
popen函式允許乙個程式將另乙個程式作為新程序來啟動,並可以傳遞資料給它或者通過它接收資料。command字串是要執行的程式名和相應的引數,open_mode必須且只能是」r」或者」w」。
如果open_mode是r,被呼叫程式的輸出就可以被呼叫程式使用,呼叫程式利用popen函式返回的file*檔案流指標,就可以通過常用的stdio庫函式(如fread)來讀取被調程式的輸出。如果open_mode是w,呼叫程式就可以用fwrite呼叫向被呼叫程式傳送資料,而被呼叫程式可以在自己的標準輸入上讀取這些資料。popen函式在失敗時返回乙個空指標。如果想通過管道實現雙向通訊,最普通的解決辦法就是使用兩個管道。
pclose函式:
用popen啟動程序結束時,我們可以用pclose函式關閉與之關聯的檔案流,pclose呼叫只在popen啟動的程序結束後才返回。如果呼叫pclose時它仍在執行,pclose呼叫將等待該程序的結束。pclose呼叫的返回值通常是它所關閉的檔案流所在程序的退出碼。如果呼叫程序在呼叫pclose之前執行了乙個wait語句,被呼叫程序的退出狀態就會丟失,因為被調程序已經結束。此時,pclose將返回-1並設定errno為echild。
3.pipe呼叫
popen函式比pipe高階,pipe函式是底層函式,通過這個函式可以在兩個程式之間傳遞資料且不需要啟動乙個shell來解釋請求的命令。
#include
int pipe(int file_descriptor[2]);
pipe函式的引數是由兩個整數型別的檔案描述符組成的陣列的指標。該函式在陣列中填上兩個新的檔案描述符之後返回0,如果失敗則返回-1。兩個返回的檔案描述符以一種特殊的方式連線起來,寫到file_descriptor[1]的所有資料都可以從file_descriptor[0]讀出來,這樣就能夠實現兩個程序之間的通訊。如果嘗試往file_descriptor[0]寫資料並從file_descriptor[1]讀資料,這樣的操作是未定義的,所以結果會非常奇怪。
4.下面介紹一種用普通管道連線兩個程序的更簡潔的方法。我們把其中乙個管道檔案描述符設定為乙個已知值,一般是標準輸入0或標準輸出1。在父程序中做這個設定稍微有點複雜,但它使得子程式的編寫變得非常簡單。這樣做的最大好處是我們可以呼叫標準程式,即那些不需要以檔案描述符為引數的程式。為了完成這個工作,我們需要使用dup函式。
#include
int dup(int file_descriptor);
int dup2(int file_descriptor_one, int file_descriptor_two);
dup呼叫的目的是開啟乙個新的檔案描述符,這與open呼叫有點類似。不同之處是,dup呼叫建立的新檔案描述符與作為它的引數的那個已有檔案描述符指向同乙個檔案(或管道)。對於dup函式來說,新的檔案描述符總是取最小的可用值。而對於dup2函式來說,它所建立的新檔案描述符或者與引數file_descriptor_two相同,或者是第乙個大於該引數的可用值。
解析:dup是如何實現程序間傳遞資料的?訣竅就在於,標準輸入的檔案描述符總是0,而dup返回的新的檔案描述符又總是最小的可用的數字。因此,如果我們首先關閉檔案描述符0然後呼叫dup,那麼新的檔案描述符就將是數字0。因為新的檔案描述符是複製乙個已有的檔案描述符,所以標準輸入就會改為指向乙個我們傳遞給dup函式的檔案描述符所對應的檔案或管道。我們建立了兩個檔案描述符,他們指向同乙個檔案或管道,而且其中之一就是標準輸入。
《TCP IP網路程式設計》第十一章 程序間通訊
include intpipe int filedes 2 filedes 0 通過管道接收資料時使用的檔案描述符,管道出口 filedes 1 通過管道傳輸資料時使用的檔案描述符,管道入口 成功返0,失敗返 1通過乙個管道進行資料互動 資料進入管道後成為無主資料,誰先呼叫read誰先獲取資料,故將...
Linux C王者歸來 第十一章 程序控制
1.程式可以有多個程序,乙個程序與程序id11 對應 2.proc中的數字對應id號,getpid和getppid可以獲得程序id父程序id 3.getuid geteuid 獲得程序使用者id和有效使用者id 4.getgid和getegid獲得程序的組id合有效組id 5.程序id和父程序id不...
modern c design 第十一章
本章介紹了經常遇到的雙分派的一種泛型解決方案。c 在語法上實現了單分派,即虛函式,通過動態機制選擇相應的函式。雙分派是形如fun object1 a,object2 b 根據a和b的實際型別動態自動分派乙個處理函式。最容易想到的方案,蠻幹法 寫一大堆過載函式.不過這種方法會有很強的依賴性。也提供了一...