有名管道相關的關鍵概念
管道應用的乙個重大限制是它沒有名字,因此,只能用於具有親緣關係的程序間通訊,在有名管道(named pipe或fifo)提出後,該限制得到了克服。fifo不同於管道之處在於它提供乙個路徑名與之關聯,以fifo的檔案形式存在於檔案系統中。這樣,即 使與fifo的建立程序不存在親緣關係的程序,只要可以訪問該路徑,就能夠彼此通過fifo相互通訊(能夠訪問該路徑的程序以及fifo的建立程序之 間),因此,通過fifo不相關的程序也能交換資料。值得注意的是,fifo嚴格遵循先進先出(first in first out),對管道及fifo的讀總是從開始處返回資料,對它們的寫則把資料新增到末尾。它們不支援諸如lseek()等檔案定位操作。
2.2有名管道的建立
#include
#include
int mkfifo(const char * pathname, mode_t mode)
該 函式的第乙個引數是乙個普通的路徑名,也就是建立後fifo的名字。第二個引數與開啟普通檔案的open()函式中的mode 引數相同。如果mkfifo的第乙個引數是乙個已經存在的路徑名時,會返回eexist錯誤,所以一般典型的呼叫**首先會檢查是否返回該錯誤,如果確實 返回該錯誤,那麼只要呼叫開啟fifo的函式就可以了。一般檔案的i/o函式都可以用於fifo,如close、read、write等等。
2.3有名管道的開啟規則
有名管道比管道多了乙個開啟操作:open。
fifo的開啟規則:
如果當前開啟操作是為讀而開啟fifo時,若已經有相應程序為寫而開啟該fifo,則當前開啟操作將成功返回;否則,可能阻塞直到有相應程序為寫而開啟該fifo(當前開啟操作設定了阻塞標誌);或者,成功返回(當前開啟操作沒有設定阻塞標誌)。
如果當前開啟操作是為寫而開啟fifo時,如果已經有相應程序為讀而開啟該fifo,則當前開啟操作將成功返回;否則,可能阻塞直到有相應程序為讀而開啟該fifo(當前開啟操作設定了阻塞標誌);或者,返回enxio錯誤(當前開啟操作沒有設定阻塞標誌)。
對開啟規則的驗證參見 附2。
2.4有名管道的讀寫規則
從fifo中讀取資料:
約定:如果乙個程序為了從fifo中讀取資料而阻塞開啟fifo,那麼稱該程序內的讀操作為設定了阻塞標誌的讀操作。
* 如果有程序寫開啟fifo,且當前fifo內沒有資料,則對於設定了阻塞標誌的讀操作來說,將一直阻塞。對於沒有設定阻塞標誌讀操作來說則返回-1,當前errno值為eagain,提醒以後再試。
* 對於設定了阻塞標誌的讀操作說,造成阻塞的原因有兩種:當前fifo內有資料,但有其它程序在讀這些資料;另外就是fifo內沒有資料。解阻塞的原因則是fifo中有新的資料寫入,不論信寫入資料量的大小,也不論讀操作請求多少資料量。
* 讀開啟的阻塞標誌只對本程序第乙個讀操作施加作用,如果本程序內有多個讀操作序列,則在第乙個讀操作被喚醒並完成讀操作後,其它將要執行的讀操作將不再阻塞,即使在執行讀操作時,fifo中沒有資料也一樣(此時,讀操作返回0)。
* 如果沒有程序寫開啟fifo,則設定了阻塞標誌的讀操作會阻塞。
注:如果fifo中有資料,則設定了阻塞標誌的讀操作不會因為fifo中的位元組數小於請求讀的位元組數而阻塞,此時,讀操作會返回fifo中現有的資料量。
向fifo中寫入資料:
約定:如果乙個程序為了向fifo中寫入資料而阻塞開啟fifo,那麼稱該程序內的寫操作為設定了阻塞標誌的寫操作。
對於設定了阻塞標誌的寫操作:
* 當要寫入的資料量不大於pipe_buf時,linux將保證寫入的原子性。如果此時管道空閒緩衝區不足以容納要寫入的位元組數,則進入睡眠,直到當緩衝區中能夠容納要寫入的位元組數時,才開始進行一次性寫操作。
* 當要寫入的資料量大於pipe_buf時,linux將不再保證寫入的原子性。fifo緩衝區一有空閒區域,寫程序就會試圖向管道寫入資料,寫操作在寫完所有請求寫的資料後返回。
對於沒有設定阻塞標誌的寫操作:
* 當要寫入的資料量大於pipe_buf時,linux將不再保證寫入的原子性。在寫滿所有fifo空閒緩衝區後,寫操作返回。
* 當要寫入的資料量不大於pipe_buf時,linux將保證寫入的原子性。如果當前fifo空閒緩衝區能夠容納請求寫入的位元組數,寫完後成功返回;如果當前fifo空閒緩衝區不能夠容納請求寫入的位元組數,則返回eagain錯誤,提醒以後再寫;
對fifo讀寫規則的驗證:
下面提供了兩個對fifo的讀寫程式,適當調節程式中的很少地方或者程式的命令列引數就可以對各種fifo讀寫規則進行驗證。
21 有名管道fifo
1.特點 有名管道 在磁碟上有這樣乙個檔案,可通過命令ls l檢視字首帶p的檔案 偽檔案,在磁碟上大小永遠為0 在核心中有乙個對應的緩衝區 半雙工的通訊方式 預設阻塞 2.使用場景 沒有血緣關係的程序間通訊 3.建立方式 命令 mkfifo 管道名 函式 mkfifo 類似於mkdir 4.fifo...
linux 有名管道(FIFO)
管道的緩衝區是有限的 管道制存在於記憶體中,在管道建立時,為緩衝區分配乙個頁面大小 管道所傳送的是無格式位元組流,這就要求管道的讀出方和寫入方必須事先約定好資料的格式,比如多少位元組算作乙個訊息 或命令 或記錄 等等 多個寫程序,乙個讀程序。可以參考我之前的部落格 一旦設定了阻塞標誌,呼叫mkfif...
Linux c 管道和有名管道(FIFO)
一.管道 1.只能用於具有親緣關係的程序之間的通訊 2.半雙工通訊模式 3.一種特殊的檔案,是一種只存在於核心中的讀寫函式 管道基於檔案描述符,管道建立時,有兩個檔案描述符 a.fd 0 固定用於讀管道 b.fd 1 固定用於寫管道 建立管道 pipe 一般步驟 1.pipe 建立管道 2.fork...