程序間通訊之FIFO

2021-09-08 17:07:22 字數 2944 閱讀 1021

fifo有時被稱為命名管道。管道只能由相關程序使用,這些相關程序的共同祖先程序建立了管道。但是,通過fifo,不相關的程序也能交換資料

fifo是一種檔案型別(參考結構(成員st_mode的編碼指明檔案是否是fifo型別。可以用s_isfifo()巨集對此進行測試。

建立fifo類似於建立檔案。確實,fifo的路徑名存在於檔案系統中。

#include int mkfifo(const

char *pathname, mode_t mode);

返回值:若成功則返回0,若出錯則返回-1

mkfifo函式中mode引數的規格說明與open函式中的mode相同(見具體的mode取值見新fifo的使用者和組的所有權規則與中所述的相同。

一旦已經用mkfifo建立了乙個fifo,就可用open開啟它。其實,一般的檔案i/o函式(close、read、write、unlink等)都可用於fifo。

應用程式可以用mknod函式建立fifo。posix.1原先並沒有包括mknod函式,它首先提出了mkfifo。mknod現在已包括在xsi擴充套件中。在大多數系統中,mkfifo呼叫mknod建立fifo。

posix.1也包括了對mkfifo(1)命令的支援。於是,用一條shell命令就可以建立乙個fifo,然後用一般的shell i/o重定向對其進行訪問。

當開啟乙個fifo時,非阻塞標誌(o_nonblock)產生下列影響:

類似於管道,若用write寫乙個尚無程序為讀而開啟的fifo,則產生訊號sigpipe。若某個fifo的最後乙個寫程序關閉了該fifo,則將為該fifo的讀程序產生乙個檔案結束標誌。

乙個給定的fifo有多個寫程序是很常見的。這就意味著如果不希望多個程序所寫的資料互相穿插,則需考慮原子寫操作。正如對於管道一樣,常量pipe_buf說明了可被原子地寫到fifo的最大資料量。

fifo有下面兩種用途:

(1)fifo由shell命令使用以便將資料從一條管道線傳送到另一條,為此無需建立中間臨時檔案。

(2)fifo用於客戶程序-伺服器程序應用程式中,以在客戶程序和伺服器程序之間傳送資料。

我們各用乙個例子來說明這兩種用途。

例項:用fifo複製輸出流

fifo可被用於複製序列管道命令之間的輸出流,於是也就不需要寫資料到中間磁碟檔案中(類似於使用管道以避免中間磁碟檔案)。管道只能用於程序間的線性連線,然而,因為fifo具有名字,所以它可用於非線性連線

考慮這樣乙個操作過程,它需要對乙個經過過濾的輸入流進行兩次處理。圖15-9表示了這種安排。

圖15-9 對乙個經過過濾的輸入流進行兩次處理

使用fifo以及unix系統程式tee(1),就可以實現這樣的過程而無需使用臨時檔案。(tee程式將其標準輸入同時複製到其標準輸出以及其命令列中包含的命名檔案中。)

mkfifo fifo1

prog3

< fifo1 &prog1

< infile | tee fifo1 | prog2

我們建立fifo,然後在後台啟動prog3,它從fifo讀資料。然後啟動prog1,用tee將其輸出傳送到fifo和prog2。圖15-10顯示了這種安排。

圖15-10 使用fifo和tee將乙個流傳送到兩個程序

例項:客戶程序-伺服器程序使用fifo進行通訊

圖15-11 客戶程序用fifo向伺服器程序傳送請求

在這種型別的客戶程序-伺服器程序通訊中使用fifo的問題是:伺服器程序如何將回答送回各個客戶程序。不能使用單個fifo,因為伺服器程序會發出對各個客戶程序請求的響應,而請求者卻不可能知道什麼時候去讀才能恰如其分地讀到對它的響應。一種解決方法是每個客戶程序都在其請求中包含它的程序id。然後伺服器程序為每個客戶程序建立乙個fifo,所使用的路徑名是以客戶程序的程序id為基礎的。例如,伺服器程序可以用名字/tmp/serv1.***xx建立fifo,其中***xx被替換成客戶程序的程序id。圖15-12顯示了這種安排。

圖15-12 客戶程序-伺服器程序用fifo進行通訊

這種安排可以工作,但也有一些不足之處。其中之一是伺服器程序不能判斷乙個客戶程序是否崩潰終止,這就使得客戶程序專用的fifo會遺留在檔案系統中。另乙個不足之處是伺服器程序必須捕捉sigpipe訊號,因為客戶程序在傳送乙個請求後沒有讀取響應就可能終止,於是留下乙個只有寫程序(伺服器程序)而無讀程序的客戶程序專用fifo。

按照圖15-12中的安排,如果伺服器程序以唯讀方式開啟眾所周知的fifo(因為它只需讀該fifo),則每當客戶程序數從1變成0時,伺服器程序就將在fifo中讀到乙個檔案結束標記。為使伺服器程序免於處理這種情況,一種常用的技巧是使伺服器程序以讀-寫方式開啟其fifo。

本篇博文內容摘自《unix環境高階程式設計》(第二版),僅作個人學習記錄所用。關於本書可參考:

程序間通訊之FIFO

管道使用起來很方便,但是沒有名字,因此只能用於具有親緣關係的程序之間進行通訊,而有名管道就克服了這一點,fifo管道提供了乙個路徑名與之相對應,即使程序不是親緣程序,只要能訪問到該路徑就能使用fifo進行通訊。有名管道的建立 include include int mkfifo const char...

程序間通訊 fifo

fifo,同時也被稱為有命管道,未命名的管道只能用於有親緣關係之間的程序間的通訊,而命名管道可以實現兩個互不相關之間程序的通訊。在linux下,我們可以通過mkfifo命令建立命名管道,fifo實際上並不占取實際的儲存空間,只是在核心pipe中的乙個鏈結。我們可以通過其大小來檢視。fifo實際結構為...

程序間通訊(FIFO)

一 有名管道 管道沒有名字,因此它們只能用於有乙個公共祖先各個程序之間的通訊,我們無法在無親緣關係的程序之間程序ipc通訊。有名管道即fifo,指先進先出,它是乙個半雙工的資料流,不同於管道的是每乙個fifo有乙個路徑名與之關聯,從而允許無 親緣之間的程序進行通訊。二 建立的函式 fifo由mkfi...