簡體   English   中英

如何避免關閉后從命名管道阻止read()

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM