繁体   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