簡體   English   中英

Posix PIPE上的非阻塞讀取和阻塞寫入

[英]Non blocking read and blocking write on Posix PIPE

我正在編寫使用posix FIFO進行通信的Client-Server應用程序。 客戶端和服務器都是單線程和單進程應用程序。

服務器設計用於處理多個客戶端。 每個客戶端都有自己的一對命名管道,一個用於從服務器向此客戶端發送消息,另一個用於從客戶端向服務器發送消息。

這個想法很簡單,Server循環遍歷所有客戶端到服務器管道,並檢查是否有東西可以在那里閱讀。

我的第一個實現是......

/* SERVER */
int desc = open(pipeName, O_RDONLY | O_NDELAY); //1
assert(desc > 0); //just simplyfing error handling
int read = read(desc, buffer, BUFSIZE); //2
if(read > 0)
  do_stuff();
close(desc); //3

/* CLIENT */
int desc = open(pipeName, O_WRONLY) //4
assert(desc > 0); //just simplyfing error handling
int read = write(desc, buffer, BUFSIZE) //5
close(desc); //6

據我所知,這段代碼無效。

有競爭條件,例如:1,2,3,3,5,6的調用順序 - 可能會導致SIGPIPE。

問題是即使PIPE的另一側沒有寫入器,非阻塞讀取打開也總是成功的。 這意味着如果客戶端將阻塞open()然后服務器執行非阻塞打開(這將解鎖客戶端)然后讀取()將返回0,因為此時PIPE中沒有任何內容,之后將關閉(),然后當控制將回到想要在打開的PIPE上執行write()的客戶端,它將導致SIGPIPE,因為讀取器不再可用(服務器已經關閉了管道)。

現在我看到兩個解決方案:

  1. 使用“tryAgain()”在客戶端處理SIGPIPE - 這看起來非常糟糕,如果我做這樣的事情,不能保證它隨時可以工作 - 它將取決於良好的命令處理順序的可能性......
  2. 繼續閱讀PIPE在服務器中一直打開(打開一次並在連接被認為完成時關閉) - 這在我的應用程序架構中是不方便的,但當然可能。 我想這會解決問題,但我不確定。

這是我的問題:

  1. 這兩種方法中的任何一種都是正確的方法嗎?
  2. 有沒有其他方法來處理這種情況?
  3. 你認為第二種解決方案能正常工作嗎?
  4. 你會選擇什么?為什么?

謝謝你的每一個答案。

我在理解你的問題時遇到了很多麻煩。 事情

客戶端將阻止open()<==打開時沒有任何塊

使用select或epoll確定哪些文件描述符是可讀寫的。

然后,只需調用那些讀取。

您將收到通知,客戶端將管道關閉為您需要處理的讀取事件,如果關閉則不會寫入。

http://linux.die.net/man/4/epoll

https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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