Linux下的IPC 命名管道的使用

2021-07-03 20:38:04 字數 2149 閱讀 5221

程序之間通過管道來進行通訊是一種常用的方法,顧名思義,管道就是一端進(寫)一端出(讀)的fifo佇列,這個佇列由核心管理,有一定大小(一般是4k),有文章上提到,如果需要修改該快取區,需要重新編譯核心(修改linux/limits.h裡pipe_buf的定義)。

需要明確的是,雖然管道在理論上是雙向的,但實際應用時,為避免複雜,都單向來用,需要雙向通訊時,採用兩個管道進行。

具有親緣關係的程序可以採用匿名管道,沒有親緣關係的程序採用命名管道,本文以命名管道為主進行討論。

建立管道

int mkfifo(const char * pathname,mode_t mode);

開啟管道

int open(const char *pathname,int oflag,... /* mode_t mode */);

讀寫int read(int handle, void *buf, int nbyte)

int write(int handle, void *buf, int nbyte)

關閉close(int handle)

這些函式都比較簡單,不做深入說明。

同檔案、網路等一樣,通過在open方法中是否設定o_nonblock標誌,管道操作有兩種執行方式:阻塞和非阻塞模式。

1.      阻塞模式

阻塞模式下,無論是讀端或寫端,如果對方沒有開啟,open都會阻塞,而write和read的行為見表1。該錶總結的場景是讀端和寫端都已順利開啟,雙方程序呼叫write或read發生的情況。

表1  阻塞模式下write和read行為

寫端程序

讀端程序

關閉管道中還有資料

可繼續讀取

未關閉管道中沒有資料

不阻塞,返回0

未關閉管道中沒有資料

阻塞管道寫滿,阻塞

寫資料,收到訊號sigpipe,導致程序異常終止

關閉 2.非阻塞模式

無論是讀端或寫端,open不會阻塞。在雙方都順利開啟後,即使沒有資料,read不會阻塞,返回-1,errno置為11。write也不會阻塞。

下面**分讀端和寫端,屬於兩個程序,分別編譯執行。寫端寫十次後退出,讀端如果讀到的資料是「exit",退出。

寫資料端

#include #include #include #include #include #define  fifo_name  "mynamedpipe"

int main()

printf("trying to opening named pipe for writing.\n");

fifo_fd = open(fifo_name, o_wronly);

printf("opened named pipe for writing.\n");

int i;

for(i=0;i<10;i++)

close(fifo_fd);

return 0;

}

讀資料端

#include #include #include #include #define  fifo_name  "mynamedpipe"

int main()

printf("trying to open named pipe for reading... \n");

fifo_fd = open(fifo_name, o_rdonly);

printf("opened named pipe for reading. \n");

while(1)

else

} close(fifo_fd);

return 0;

}

命名管道會真的在磁碟上建立乙個管道檔案,該檔案的大小始終為0,例如,對上面的**,會建立乙個叫mynamedpipe的檔案(個人感覺似乎無此必要,不知設計者是如何考慮的)。

命名管道有乙個「異常現象」,如上面的表1所示,如果讀端程序關閉了,寫端程序「寫資料」時,有可能使程序異常退出,不知設計者出於什麼考慮,本人感覺此時write函式返回乙個錯誤更為妥當,由呼叫者來處理這個錯誤。這個「異常」,使得使用命名管道時應慎重,要保證讀端程序後於寫端程序關閉管道,或者採取如下兩個方法:一是遮蔽sigpipe訊號或自己處理它,二是每次寫完資料後,關閉管道,下次操作時,重新開啟(此方法嚴格來講並不可靠)。

IPC之命名管道

1.管道是通過io介面訪問得位元組流,windows中利用得是readfile 和writefile windows利用單一控制代碼支援雙向io,命名管道也稱做fifo first in first out 命名管道得機制 乙個程序把資料放到管道裡,另乙個知道管道名字得程序把資料把取走,實際是用於程...

linux的管道和命名管道

看了個教程,感覺還是要結合 看。管道是linux裡面程序間通訊的一種方式,其他的還有像訊號 signal 訊號量 訊息佇列 共享記憶體 套接字 socket 等。1.管道pipe int pipe int fd 2 返回值 成功,返回0,否則返回 1。引數陣列包含pipe使用的兩個檔案的描述符。fd...

IPC實現機制(二) 命名管道(FIFO)

一 fifo的概念 匿名管道 pipe 的 個不 之處是沒有名字,因此,只能 於具有親緣關係的程序間通訊 因此,提出了命名管道 命名管道 fifo 提供 個路徑名與之關聯,以fifo的 件形式儲存於 件系統中。命名管道是 個裝置 件,因此,即使程序與建立fifo的程序不存在親緣關係,只要可以訪問該路...