linux下管道讀寫阻塞的相關問題

Linux管道讀寫阻塞
轉載 2015年03月11日 18:02:08 2146
來自度娘:
寫管道時:
向管道中寫入數據:
向管道中寫入數據時,linux將不保證寫入的原子性,管道緩衝區一有空閒區域,寫進程就會試圖向管道寫入數據。如果讀進程不讀走管道緩衝區中的數據,那麼寫操作將一直阻塞。
對於沒有設置阻塞標誌的寫操作:(1)當要寫入的數據量不大於PIPE_BUF時,Linux將保證寫入的原子性。如果當前FIFO空閒緩衝區能夠容納請求寫入的字節數,寫完後成功返回;如果當前FIFO空閒緩衝區不能夠容納請求寫入的字節數,則返回EAGAIN錯誤,提醒以後再寫。(2)當要寫入的數據量大於PIPE_BUF時,Linux將不再保證寫入的原子性。在寫滿所有FIFO空閒緩衝區後,寫操作返回。
注:只有在管道的讀端存在時,向管道中寫入數據纔有意義。否則,向管道中寫入數據的進程將收到內核傳來的SIFPIPE信號,應用程序可以處理該信號,也可以忽略(默認動作則是應用程序終止)。
管道寫端關閉後,寫入的數據將一直存在,直到讀出爲止。

讀管道時:
如果管道的寫端不存在,則認爲已經讀到了數據的末尾,讀函數返回的讀出字節數爲0;
當管道的寫端存在時,如果請求的字節數目大於PIPE_BUF,則返回管道中現有的數據字節數,如果請求的字節數目不大於PIPE_BUF,則返回管道中現有數據字節數(此時,管道中數據量小於請求的數據量);或者返回請求的字節數(此時,管道中數據量不小於請求的數據量)。
注:(PIPE_BUF在include/linux/limits.h中定義,不同的內核版本可能會有所不同。Posix.1要求PIPE_BUF至少爲512字節,red hat 7.2中爲4096)。
以下的轉載:http://blog.csdn.net/MONKEY_D_MENG/article/details/5570468
1.從FIFO中讀取數據:
約定:如果一個進程爲了從FIFO中讀取數據而阻塞打開了FIFO,那麼稱該進程內的讀操作爲設置了阻塞標誌的讀操作。
(1)如果有進程寫打開FIFO,且當前FIFO爲空,則對於設置了阻塞標誌的讀操作來說,將一直阻塞下去,直到有數據可以讀時才繼續執行;對於沒有設置阻塞標誌的讀操作來說,則返回0個字節,當前errno值爲EAGAIN,提醒以後再試。
(2)對於設置了阻塞標誌的讀操作來說,造成阻塞的原因有兩種:一、當前FIFO內有數據,但有其它進程在讀這些數據;二、FIFO本身爲空。
解阻塞的原因是:FIFO中有新的數據寫入,不論寫入數據量的大小,也不論讀操作請求多少數據量,只要有數據寫入即可。
(3)讀打開的阻塞標誌只對本進程第一個讀操作施加作用,如果本進程中有多個讀操作序列,則在第一個讀操作被喚醒並完成讀操作後,其它將要執行的讀操作將不再阻塞,即使在執行讀操作時,FIFO中沒有數據也一樣(此時,讀操作返回0)。
(4)如果沒有進程寫打開FIFO,則設置了阻塞標誌的讀操作會阻塞。
(5)如果FIFO中有數據,則設置了阻塞標誌的讀操作不會因爲FIFO中的字節數少於請求的字節數而阻塞,此時,讀操作會返回FIFO中現有的數據量。

2.從FIFO中寫入數據:
約定:如果一個進程爲了向FIFO中寫入數據而阻塞打開FIFO,那麼稱該進程內的寫操作爲設置了阻塞標誌的寫操作。
FIFO的長度是需要考慮的一個很重要因素。系統對任一時刻在一個FIFO中可以存在的數據長度是有限制的。它由#define PIPE_BUF定義,在頭文件limits.h中。在Linux和許多其他類UNIX系統中,它的值通常是4096字節,Red Hat Fedora9下是4096,但在某些系統中它可能會小到512字節。
雖然對於只有一個FIFO寫進程和一個FIFO的讀進程而言,這個限制並不重要,但只使用一個FIFO並允許多個不同進程向一個FIFO讀進程發送請求的情況是很常見的。如果幾個不同的程序嘗試同時向FIFO寫數據,能否保證來自不同程序的數據塊不相互交錯就非常關鍵了à也就是說,每個寫操作必須“原子化”。

一、對於設置了阻塞標誌的寫操作:
(1)當要寫入的數據量不大於PIPE_BUF時,Linux將保證寫入的原子性。如果此時管道空閒緩衝區不足以容納要寫入的字節數,則進入睡眠,直到當緩衝區中能夠容納要寫入的字節數時,纔開始進行一次性寫操作。即寫入的數據長度小於等於PIPE_BUF時,那麼或者寫入全部字節,或者一個字節都不寫入,它屬於一個一次性行爲,具體要看FIFO中是否有足夠的緩衝區。
(2)當要寫入的數據量大於PIPE_BUF時,Linux將不再保證寫入的原子性。FIFO緩衝區一有空閒區域,寫進程就會試圖向管道寫入數據,寫操作在寫完所有請求寫的數據後返回。

二、對於沒有設置阻塞標誌的寫操作:
(1)當要寫入的數據量不大於PIPE_BUF時,Linux將保證寫入的原子性。如果當前FIFO空閒緩衝區能夠容納請求寫入的字節數,寫完後成功返回;如果當前FIFO空閒緩衝區不能夠容納請求寫入的字節數,則返回EAGAIN錯誤,提醒以後再寫。
(2)當要寫入的數據量大於PIPE_BUF時,Linux將不再保證寫入的原子性。在寫滿所有FIFO空閒緩衝區後,寫操作返回

發佈了11 篇原創文章 · 獲贊 21 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章