Linux系統程式設計 管道和FIFO

2021-10-02 10:54:11 字數 2852 閱讀 6615

$ ls | wc -l

為執行上述命令,shell建立了兩個程序來分別執行ls和wc。通過管道連線兩個程序。

管道是單向的,允許資料從乙個程序流向另乙個程序。

管道是乙個位元組流意味著在使用管道時不存在訊息或訊息邊界。從管道中讀取資料的程序可以讀取任意大小的資料塊,而不管寫入程序寫入管道的資料塊大小。通過管道的資料是有順序的。並且,在管道中無法使用lseek()來隨機的訪問資料。

試圖從乙個當前為空的管道中讀取資料將會被阻塞直至少有乙個位元組被寫入管道中為止。如果寫入端被關閉了,那麼從管道中讀取資料的程序在讀完管道中剩餘所有資料之後會看到檔案結束(read()返回0)

如果多個程序寫入同乙個管道,那麼如果他們在乙個時刻寫入的資料量不超過pipe_buf位元組,那麼就可以保證寫入的資料不會發生相互混合的情況。在linux上pipe_buf為4096.

當寫入的資料塊的大小超過pipe_buf位元組,那麼核心可能會將資料分割成幾個較小的片段傳輸。

#include

intpipe

(int filefd[2]

);

成功呼叫的pipe會在陣列filefd中返回兩個開啟的檔案描述符:乙個表示管道的讀取端(filefd[0]),乙個表示管道的寫入端(filefd[1])。

可以對返回的描述符進行read,write。也可以使用fdopen()獲取檔案流來進行stdio函式操作。

fork()之後,子程序會繼承父程序的檔案描述符副本。

應當在fork之後立即關閉某一端,保證管道是單向的。

讀取端應關閉寫入端,這樣在當其他程序完成輸出並關閉寫入端之後,讀者可以看到檔案結束。如果本身沒有關閉寫入端,那麼將不會看到結束read將一直阻塞。

寫入端也應當關閉讀取端,當乙個程序試圖向乙個管道中寫入資料但沒有任何程序擁有該管道的開啟這點讀取描述符時,核心會向該程序傳送sigpipe訊號。預設情況下會殺死乙個程序。但可以通過signal進行忽略或捕獲,會導致write返回epipe錯誤而失敗。如果沒有關閉,則會慢慢充滿整個管道,直至阻塞。

下面的**是建立兩個管道,啟用父子程序進行雙向通訊。父程序迴圈從標準輸入讀取文字塊使用管道傳送給子程序,子程序轉換成大寫在通過另乙個管道發回父程序。父程序讀取並反饋到標準輸出上。ctrl c停止

#include

#include

#include

#include

#include

#include

#include

#include

#include

bool flag;

void

handler

(int sig)

intmain()

write

(fd2[1]

,buf1,ret);if

(!flag)

break;}

close

(fd1[0]

);close

(fd2[1]

);printf

("child exit");

_exit

(exit_success)

;default

:close

(fd1[0]

);close

(fd2[1]

);while

((ret=

read

(stdin_fileno,buf,

1024))

!=0)close

(fd1[1]

);close

(fd2[0]

);wait

(null);

printf

("parent exit");

exit

(exit_success);}

}

和管道類似,不同在於fifo在檔案系統中擁有乙個名稱,其開啟方式和普通檔案一樣。可以用於非相關程序之間的通訊。

#include

intmkfifo

(const

char

*pathname,mode_t mode)

;

一旦fifo被建立,任何程序都能夠開啟它。

一般使用fifo,都以某一種讀取方式開啟,如果要讀則open( ,o_rdonly)操作將會阻塞到另乙個程序開啟fifo 的寫入端。當開啟乙個fifo使用o_rdwr標誌來繞開阻塞行為時。open()會立即返回,但不能在返回的檔案描述符上進行任何操作。因為這種做法破壞了fifo 的i/o模型。

可以通過open指定o_nonblock標記來進行非阻塞的開啟操作。

《linux/unix系統程式設計手冊》

Linux系統程式設計之管道通訊

toc 侷限性 資料自己讀不能自己寫。資料一旦被讀走,便不在管道中存在,不可反覆讀取。由於管道採用半雙工通訊方式。因此,資料只能在乙個方向上流動。只能在有公共祖先的程序間使用管道。pipe的demo include include include include include include in...

Linux系統程式設計 fifo命名管道

fifo也被稱為命名管道。未命名的管道只能在兩個相關的程序之間使用,而且這兩個程序還有乙個共同的建立了他們的祖先程序,但是fifo,不相關的程序也能交換資料。fifo是一種檔案型別,fifo的建立有兩種方式。1.直接用命令建立 mkfifo 2.利用函式建立 int mkfifo const cha...

Linux系統程式設計之管道通訊

int pipe fd 2 fd 0 read fd 1 write fork 管道一般讀寫行為 讀 資料 位元組數 無資料寫端全部關閉 read 0 讀到結尾 仍有寫端開啟 阻塞等待 寫 讀端全閉關 程式異常終止 sigpipe 讀端仍有開啟 管道寫滿 阻塞等待 未滿 返回實際寫入的位元組數.li...