1. 程式人生 > >命名管道建立和讀寫

命名管道建立和讀寫

2.3 有名管道的開啟規則
有名管道比管道多了一個開啟操作:open。
FIFO的開啟規則:
如果當前開啟操作是為讀而開啟FIFO時,若已經有相應程序為寫而開啟該FIFO,則當前開啟操作將成功返回;否則,可能阻塞直到有相應程序為寫而開啟該FIFO(當前開啟操作設定了阻塞標誌);或者,成功返回(當前開啟操作沒有設定阻塞標誌)。
如果當前開啟操作是為寫而開啟FIFO時,如果已經有相應程序為讀而開啟該FIFO,則當前開啟操作將成功返回;否則,可能阻塞直到有相應程序為讀而開啟該FIFO(當前開啟操作設定了阻塞標誌);或者,返回ENXIO錯誤(當前開啟操作沒有設定阻塞標誌)。
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讀寫規則進行驗證。

程式1:寫FIFO的程式