管道是用於相關過程之間的通訊。 我們是否可以使用管道進行不相關的程序通訊,比方說,我們要從乙個終端執行客戶端程式,從另乙個終端執行伺服器程式? 答案是否定的。那麼怎樣才能實現不相關的程序通訊,簡單的答案就是使用 命名管道。 即使這適用於相關的程序,但是使用命名管道進行相關的程序通訊沒有任何意義。
我們使用乙個管道進行單向通訊,兩個管道進行雙向通訊。 命名管道是否適用相同的條件。 答案是否定的,我們可以使用單一命名管道作為命名管道支援雙向通訊(伺服器和客戶端之間的通訊,同時還有客戶端和伺服器之間的通訊)。
命名管道的另乙個名稱是fifo(先進先出)。 讓我們看看系統呼叫(mknod())來建立乙個命名管道,這是一種特殊的檔案。
#include
#include
#include
#include
int mknod(const char *pathname, mode_t mode, dev_t dev);
這個系統呼叫將建立乙個特殊的檔案或檔案系統節點,如普通檔案,裝置檔案或fifo。 系統呼叫的引數是路徑名,模式和dev。 路徑名以及模式和裝置資訊的屬性。 路徑名是相對的,如果沒有指定目錄,它將在當前目錄中建立。 指定的模式是指定檔案型別的檔案模式,如下表中所述的檔案型別和檔案模式。 開發領域是指定裝置資訊,如主要和次要裝置號碼。
檔案型別
描述檔案型別
描述s_ifblk
指定塊s_ifreg
普通檔案
s_ifchr
指定字元
s_ifdir
目錄s_ififo
指定fifo
s_iflnk
符號鏈結
檔案模式
檔案模式
描述檔案模式
描述s_irwxu
所有者讀,寫,執行/搜尋
s_iwgrp
寫入許可權,組
s_irusr
讀取許可權,所有者
s_ixgrp
執行/搜尋許可權,組
s_iwusr
寫入許可權,所有者
s_irwxo
讀,寫,執行/由他人搜尋
s_ixusr
執行/搜尋許可權,所有者
s_iroth
讀取許可權,其他
s_irwxg
讀,寫,執行/按組搜尋
s_iwoth
寫許可權,其他
s_irgrp
讀取許可權,組
s_ixoth
執行/搜尋許可權,其他
檔案模式也可以用八進位制表示法表示,如0xyz,其中x表示所有者,y表示組,z表示其他。 x,y或z的取值範圍為0〜7,讀,寫,執行的取值分別為4,2,1。 如果需要結合讀取,寫入和執行,則相應地新增值。
如果使用的是0640,那麼這意味著對所有者的讀寫(4 + 2 = 6),對於組讀取(4)和對其他人沒有許可權(0)。
這個呼叫在成功時將返回0,在失敗的情況下為-1。 要知道失敗的原因,請檢查errno變數或perror()函式。
#include
#include
int mkfifo(const char *pathname, mode_t mode)
這個庫函式建立乙個fifo專用檔案,用於命名管道。 這個函式的引數是檔名和模式。 檔名可以是絕對路徑或相對路徑。 如果未提供完整路徑名(或絕對路徑),則將在執行過程的當前資料夾中建立該檔案。 檔案模式資訊如mknod()系統呼叫中所述。
這個呼叫在成功時將返回0,在失敗的情況下為-1。 要知道失敗的原因,請檢查errno變數或perror()函式。
讓我們考慮在乙個終端上執行伺服器並在另乙個終端上執行客戶端的程式。 該方案只會進行單向溝通。 客戶端接受使用者輸入並將訊息傳送到伺服器,伺服器在輸出上列印訊息。 這個過程一直持續到使用者輸入字串「end」。
讓我們通過乙個例子來理解這一點 -
第1步- 建立兩個程序,乙個是fifoserver,另乙個是fifoclient。
第2步 - 伺服器程序執行以下操作 -
建立乙個名為「myfifo」的命名管道(使用系統呼叫mknod())。
開啟命名管道為唯讀目的。
在這裡,建立了具有對所有者的讀寫許可權的fifo。讀取群組,沒有其他人的許可權。
等待客戶的訊息。
如果從客戶端收到的訊息不是「end」,則列印該訊息。 如果訊息是「end」,則關閉fifo並結束該程序。
第3步 - 客戶端程序執行以下操作 -
開啟命名管道僅用於寫入目的。
接受來自使用者的字串。
檢查如果使用者輸入是否為"end"。如果字串是「end」,則會關閉fifo並結束程序。
無限重複,直到使用者輸入字串「end」。
現在我們來看看fifo伺服器檔案的實現 -
/* filename: fifoserver.c */
#include
#include
#include
#include
#include
#include
#define fifo_file "myfifo"
int main() else else {
write(fd, readbuf, strlen(readbuf));
printf("fifoclient: sent string: \"%s\" and string length is %d\n", readbuf, (int)strlen(readbuf));
close(fd);
break;
return 0;
編譯和執行輸出結果 -
fifo_client: send messages, infinitely, to end enter "end"
enter string: linux ipcs
fifoclient: sent string: "linux ipcs" and string length is 10
fifoclient: received string: "scpi xunil" and length is 10
enter string: inter process communication
fifoclient: sent string: "inter process communication" and string length is 27
fifoclient: received string: "noitacinummoc ssecorp retni" and length is 27
enter string: end
fifoclient: sent string: "end" and string length is 3
¥ 我要打賞
糾錯/補充
收藏加qq群啦,易百教程官方技術學習群
注意:建議每個人選自己的技術方向**,同乙個qq最多限加 3 個群。
命名管道 匿名管道
有名字 則可以通過 名字 開啟相同的管道進行通訊,沒有名字 在核心中沒有明確標識 只能通過 子程序複製父程序的方式實現通訊,複製了檔案描述符 匿名管道只能用於具有親緣關係的程序間通訊。只要在建立程序之前建立管道,後邊的程序都可以實現通訊。命名管道可用於同一主機任意程序間通訊 作業系統在核心提供的一塊...
命名管道的使用
我在工作中碰到了乙個這樣的問題,有兩個程式,第乙個程式會fork乙個程序exec呼叫第二個程式,這樣呼叫後,第乙個程式還是繼續執行父程序的。我要求第乙個程式的父程序停止執行,直到第二個程式退出或執行到某個時候才繼續執行。下面是兩個例子程式的 先執行gui程式,再執行player程式 gui 在後台執...
普通管道和命名管道
2116 0 管道分為普通管道和命名管道 兩者都是半雙工的。普通管道只能用於父子程序或兄弟程序間的通訊,因為普通管道通過fork呼叫來拷貝檔案描述符的,在檔案系統中,普通管道並不對應物理檔案。命名管道在檔案系統中有物理檔案存在,因此可以用於非親屬的程序間通訊。include int pipe int...