[英]How to avoid blocking read() from named pipe after it closes
我有兩個使用命名管道創建的進程。 編寫器進程使用write()編寫一條消息,而讀取器進程通過read()讀取該消息。 我注意到當作者關閉管道時,read()會阻塞。 是否可以讓編寫器進程在關閉管道之前發送EOF,以便不會阻塞閱讀器?
不能...無法發送EOF
因為EOF
不能映射到通過通道發送的內容。 EOF
條件(是的,這是一個條件,不是您通過通道接收或發送的條件),意味着沒有更多數據要read(2)
並且它是通過使read(2)
返回讀取的0個字符得到的。 與在EOF
條件下進行的許多讀取一樣,它們將返回0
值,表示沒有更多數據。
順便說一句,當沒有可用數據時,管道會阻止讀取器,但是由於編寫器仍在發送更多數據,因此沒有EOF條件。 按照設計,當沒有可用數據時,管道將阻止讀取器(但寫入器仍處於打開狀態);當沒有更多空間將數據放入fifo中時,管道將阻塞寫入器(這種情況在有fifo打開的讀取器中發生,但沒有他們正在閱讀),如您所見,它是一項功能,而不是錯誤。
如果要使read(2)
處於非阻塞狀態並且在沒有可用數據時將其設置為0
,則可以使用O_NONBLOCK
標志open(2)
(或稍后通過fcntl(2)
系統調用進行操作),這將使read(2)
fcntl(2)
read(2)
立即返回可用數據(即使沒有可用數據),但是它有一個缺點:那么您無法將沒有可用數據(尚未寫入)的fifo與實際的EOF
(作者關閉了它的作者)區分開來。 ),因為兩者都將返回0
。
順便說一句,在談論文件條件結束時,我不喜歡使用EOF
常量,因為它增加了對其定義的混淆。 EOF
是文件條件結束時 getchar(3)
返回的值,但不是char
(如果檢查getchar(3)
的定義,您會發現它的定義為int
而不是char
,這是為了添加EOF
條件限制為可能的char
值的整個范圍---因此,從getchar(3)
返回257個可能的值,數據為0-256
,文件結束條件為EOF
)
如果要讓編寫者發信號通知文件結束,則必須close(2)
fifo並重新打開它。
當編寫器關閉管道時,即使它被阻塞(例如,它將醒來),讀取器也不會阻塞。 讀調用將返回0,指示管道上的EOF。 讀者應該這樣做:
rlen = read(pipefd,buf,sizeof(buf));
if (rlen <= 0)
break;
您是否正在檢查返回碼?
在寫入器中,如果讀取器過早關閉了管道(例如,它已中止),則寫入器將從寫入-1並將errno設置為EPIPE時獲得返回。 它還可以獲取SIGPIPE。
見男人7管...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.