程序間通訊之FIFO

2021-06-13 13:27:25 字數 2491 閱讀 4498

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

有名管道的建立:

#include 

#include 

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

第乙個引數是建立的fifo的路徑名字,如果存在該路徑,那麼會返回eexit錯誤。

第二個引數和開啟普通檔案的open函式的mode引數一樣。

一般檔案的io函式都可以用於fifo,有名管道和管道相比,其多了乙個開啟的操作,使用open函式開啟已經建立的fifo。

如果當前操作是為讀而開啟fifo,那麼必須保證此時有乙個程序為寫而開啟改fifo,否則會阻塞的等待有乙個程序為寫而開啟該fifo。

如果當前操作是為寫而開啟fifo,那麼必須保證此時有乙個程序為讀而開啟該fifo,否則會阻塞的等待有乙個程序為讀而開啟該fifo。

從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緩衝區以有空閒區域,寫程序就會試圖向fifo寫資料,寫操作在寫完所有請求寫的資料後返回。

對於沒有設定阻塞標記的寫操作:

當要寫入的資料量大於pipe_buf時,linux將不再保證寫入的原子性,在寫滿所有fifo空閒緩衝區後,寫操作返回。

當要寫入的資料量不大於pipe_buf時,linux將保證寫入的原子性。如果當前fifo空閒緩衝區能夠容納的請求寫入的位元組數,寫完後返回;如果當前fifo空閒緩衝區不能夠容納請求寫入的位元組數,則返回eagain,提醒以後再寫。

下面是建立fifo、向fifo中寫資料、從fifo中讀資料的例項:

建立fifo:

#include #include #include #include #include int main(int argc, char **argv)

if ((mkfifo(argv[1], mode)) < 0)

else

return 0;

}

向fifo寫資料:

#include #include #include #include #include #include #include #include #define bufsz pipe_buf

int main(void)

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

usleep(3000*1000);

} close(fd);

return 1;

}

寫資料程式編譯後執行,由於設定阻塞標記的寫操作,所以,在沒有以讀操作而開啟fifo的程序時,寫操作一直阻塞,直到有以讀操作而開啟的fifo的程序。

從fifo中讀資料:

#include #include #include #include #include #include #include #define bufsz pipe_buf

int main(void)

while((len = read(fd, buf, bufsz)) > 0)

close(fd);

exit(0);

}

當有讀操作開啟fifo程序時,寫操作程序開始往fifo中寫資料,讀程序開始讀資料。

程序間通訊之FIFO

fifo有時被稱為命名管道。管道只能由相關程序使用,這些相關程序的共同祖先程序建立了管道。但是,通過fifo,不相關的程序也能交換資料。fifo是一種檔案型別 參考結構 成員st mode的編碼指明檔案是否是fifo型別。可以用s isfifo 巨集對此進行測試。建立fifo類似於建立檔案。確實,f...

程序間通訊 fifo

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

程序間通訊(FIFO)

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