?
一、從FIFO中讀取數據:
約定:如果一個進程為了從FIFO中讀取數據而以阻塞的方式打開FIFO,則稱內核為該進程的讀操作設置了阻塞標志。
- 如果有進程為寫而打開FIIF(寫端存在),且當前FIFO內沒有數據,則對于設置了阻塞標志的讀操作來說,將一直阻塞,對于沒有設置阻塞標志讀操作來說返回-1,當前errno值為EAGAIN提醒以后再試。
- 對于設置阻塞標志的讀操作來說,造成阻塞的原因有兩種,當前FIFO內有數據,但其他進程正在讀這些數據;另外FIFO內沒有數據。解阻塞的原因則是FIFO中有新的數據寫入,不論寫入數據量的大小,也不論讀操作請求多少數據量。
- 如果沒有進程寫打開FIFO,則設置了阻塞標志的讀操作會阻塞。
- 如果寫端關閉,管道中有數據讀取管道中的數據,如果管道沒有數據讀端將不會繼續阻塞,此時返回0。(注意:如果FIFO有數據,則設置了阻塞標志的讀操作來說不會因為FIFO的字節數小于請求讀的字節數而阻塞,讀操作會返回FIFO現有的數據量。)
?
二、向FIFO中寫入數據
約定:如果一個進程為了向FIFO中寫入數據而阻塞打開FIFO,那么稱該進程內的寫操作設置了阻塞標志。
1. 對于設置了阻塞標志的寫操作:
- 當寫入數據量不大于PIPE_BUF時,linux將保證寫入的原子性,如果此時管道空閑緩沖區不足以容納要寫入的字節數,則進入睡眠,直到緩沖區中能夠寫入的字節數,才開始進行一次性寫操作。
- 當要寫入的數據量大于PIPE_BUF時,Linux將不再保證寫入的原子性。FIFO緩沖區一有空閑,寫進程就會試圖向管道寫入數據,寫操作在寫完所有請求寫的數據后返回。
2. 對于沒有設置阻塞標志的寫操作:
- 當要寫入的數據量大于PIPE_BUF時,Linux將不再保證寫入的原子性。在寫滿所有FIFO空閑緩沖區后,寫操作返回。
- 當要寫入的數據量不大于PIPE_BUF時,linux將保證寫入的原子性,如果當前FIFO空閑緩沖區能夠容納寫入的字節數,寫完成功返回;如果當前FIFO空閑緩沖區不能容納請求寫入的字節數,則返回EANGIN錯誤,提醒以后再寫。