當管道中沒有數據並且寫端關閉時,選擇會指示管道是可讀的嗎?
我正在閱讀Linux 程式介面。
來自63.2.3 文件描述符何時準備就緒?, 它說:
正確使用
select()
並poll()
需要了解文件描述符指示準備就緒的條件。O_NONBLOCK
SUSv3 表示,如果對 I/O 函式的呼叫不會阻塞,則認為 文件描述符(帶有清除)已準備就緒,無論該函式是否實際傳輸數據。重點是斜體:告訴我們一個I/O操作是否不會阻塞,而不是它是否能成功傳輸數據select()
。poll()
有鑑於此,讓我們考慮這些系統呼叫如何針對不同類型的文件描述符進行操作。我們在包含兩列的表格中顯示此資訊:
- 該
select()
列指示文件描述符是否標記為可讀 (r)、可寫 (w) 或具有異常條件 (x)。….
管道和 FIFO
表 63-4 總結了管道或 FIFO 讀取端的詳細資訊。該
Data in pipe?
列指示管道是否至少有 1 個字節的數據可供讀取。在此表中,我們假設POLLIN
在events
欄位中指定了poll()
。….
表 63-4:管道或 FIFO 讀取端的
select()
指示poll()
Condition or event | select() | poll() Data in pipe? | Write end open? | no | no | r | POLLHUP yes | yes | r | POLLIN yes | no | r | POLLIN | POLLHUP
和表 63-5:
select()
以及poll()
管道或 FIFO 寫結束的指示(在此表中,我們假設
POLLOUT
在事件欄位中為poll()
.)指定。Condition or event | select() | poll() Space for PIPE_BUF bytes? | Read end open? | no | no | w | POLLERR yes | yes | w | POLLOUT yes | no | w | POLLOUT | POLLERR
我不明白兩個表的第一行情況。
管道中沒有數據,寫結束關閉,
select()
是否表明它是一個可讀的文件描述符?為什麼?在管道中有數據之前不應該select()
阻塞嗎?沒有
PIPE_BUF
字節空間,讀取結束關閉,select()
將表明作為可寫文件描述符?
假設您打開了管道(讀取端),沒有數據但寫入端也打開了。如果您
read()
在這種情況下執行 a,您將阻止 - 並且select()
不會將 FD 報告為可讀。我想我們在這點上是一致的,對吧?現在假設你在這個阻塞的中間,
read()
而 writerclose()
是他們的管道末端。怎麼了?您的read()
回報,結果為0
. 如果你在writer sread()
之後呼叫,幾乎會發生同樣的事情。close
只有你不會阻止 -read
會立即返回,也會有0
結果。因此,根據您引用的來源中的推理,您的 FD 是“可讀的” - 或者最好說“不可阻止”,這就是select
實際報告的內容。如果你嘗試編寫一個小例子,你會發現這個定義實際上比你似乎建議的更“直覺”的定義更乾淨、更優雅。