Joe*_*izz 9 linux ipc pipe mkfifo
我经历了不同的linux命名管道客户端/服务器实现,但大多数使用读/写的阻塞默认值.
因为我已经使用poll()来检查其他标志,所以通过poll()检查传入的FIFO数据也是个好主意...
经过所有研究后,我认为在O_RDWR模式下打开管道是在没有编写器打开管道时防止管道上无限数量的EOF事件的唯一方法.
这样管道的两端都是关闭的,其他客户端也可以打开可写端.为了回应我会使用单独的管道......
我的问题是,尽管我发现了一些使用O_RDWR标志的示例,但open()联机帮助页将此标志描述为在分配给FIFO时无法使用.(http://linux.die.net/man/3/open)
但是如何在没有O_RDWR的情况下在管道上使用poll()?你认为"O_RDWR"是打开管道的合法方式吗?
lee*_*eek 35
首先,一些预赛:
使用O_NONBLOCK和poll()是常见的做法 - 而不是相反.要成功运行,您需要确保正确处理所有状态poll()并read()返回状态:
read()0EOF的返回值- 另一方已关闭其连接.这对应于(通常,但不是在所有操作系统上)poll()返回POLLHUPrevent.您可能希望POLLHUP在尝试之前检查read(),但这并非绝对必要,因为read()保证0在写入侧关闭后返回.read()在作家已经连接之前打电话,而你已经连接,那么O_RDONLY | O_NONBLOCK你将会反复得到EOF(read()返回0),正如你所注意到的那样.但是,如果您在调用之前poll()等待POLLIN事件read(),它将等待编写器连接,而不是生成EOF.read()返回值-1通常意味着错误.但是,如果errno == EAGAIN这只是意味着现在没有更多的数据可用而且您没有阻止,那么您可以返回poll()以防其他设备需要处理.如果errno == EINTR,然后read()在读取任何数据之前被中断,您可以返回poll()或read()立即再次呼叫.现在,对于Linux:
O_RDONLY,则:
open()将阻塞,直到有相应的作家开放.poll()POLLIN当数据准备好被读取或发生EOF时,它将提供一个revent.read()将阻塞,直到读取所请求的字节数,连接关闭(返回0),它被信号中断,或发生一些致命的IO错误.这种阻止类型会破坏使用的目的poll(),这就是poll()几乎总是使用的原因O_NONBLOCK.您可以使用a在超时后alarm()唤醒read(),但这太复杂了.poll() POLLHUP重复,然后read()将0无限期地返回.此时,读者必须关闭其文件句柄并重新打开它.
O_RDONLY | O_NONBLOCK,则:
open()不会阻止.poll()POLLIN当数据准备好被读取或发生EOF时,它将提供一个revent.poll()如果没有作者,也会阻止作者可用.read()将返回-1并设置errno == EAGAIN连接是否仍处于打开状态,0如果连接已关闭(EOF)或尚未由编写器打开,则将返回.何时errno == EAGAIN,这意味着是时候返回poll(),因为连接已打开但没有更多数据.当errno == EINTR,read()还没有读取任何字节并被信号中断时,可以重新启动它.poll() POLLHUP重复,然后read()将0无限期地返回.此时,读者必须关闭其文件句柄并重新打开它.
O_RDWR,那么:
open()不会阻止.poll()POLLIN当数据准备好被读取时,它将提供一个revent.但是,对于命名管道,EOF不会导致POLLIN或发生POLLHUP.read()将阻塞,直到读取所请求的字节数,它被信号中断,或发生一些其他致命的IO错误.对于命名管道,它不会返回errno == EAGAIN,甚至也不会返回0EOF.它只会坐在那里直到读取所请求的确切字节数,或直到它收到一个信号(在这种情况下,它将返回到目前为止读取的字节数,或返回-1并设置errno == EINTR如果到目前为止没有读取字节) .O_RDWR | O_NONBLOCK,那么:
open()不会阻止.poll()POLLIN当数据准备好被读取时,它将提供一个revent.但是,EOF不会导致POLLIN或拒绝POLLHUP命名管道.read()将返回-1并设置errno == EAGAIN.这是返回poll()等待更多数据的时间,可能来自其他流.正如您所关注的那样,使用O_RDWR管道并非标准,POSIX或其他地方.
然而,由于这个问题似乎来了的时候,在Linux上的最佳途径,使"弹性命名管道"的生存,即使一方关闭,并不会引起POLLHUPrevents中或返回0的read(),就是用O_RDWR | O_NONBLOCK.
我在Linux上看到了处理命名管道的三种主要方法:
(便携式.)没有poll(),并有一个管道:
open(pipe, O_RDONLY);read()尽可能多的数据,可能循环read()调用.
read() == -1和errno == EINTR,read()一遍又一遍.read() == 0,连接已关闭,并且已收到所有数据.(便携式.)随着poll()管道,甚至是命名的管道,只打开一次,一旦它们关闭,必须由读写器重新打开,建立一个新的管道:
open(pipe, O_RDONLY | O_NONBLOCK);poll()对于POLLIN事件,可能同时在多个管道上.(注意:这可以防止read()在编写器连接之前获得多个EOF.)read()尽可能多的数据,可能循环read()调用.
read() == -1和errno == EAGAIN,请返回poll()步骤.read() == -1和errno == EINTR,read()一遍又一遍.read() == 0,连接已关闭,您必须终止,或关闭并重新打开管道.(非便携式,特定于Linux.)随着poll()并期望命名管道永不终止,并且可能多次连接和断开连接:
open(pipe, O_RDWR | O_NONBLOCK);poll()对于POLLIN事件,可能同时在多个管道上.read()尽可能多的数据,可能循环read()调用.
read() == -1和errno == EAGAIN,请返回poll()步骤.read() == -1和errno == EINTR,read()一遍又一遍.read() == 0出现问题 - 它不应该发生O_RDWR在命名管道上,而只发生在管道上O_RDONLY或未命名的管道上; 它表示一个必须关闭并重新打开的封闭管道.如果在同一poll()事件处理循环中混合使用命名管道和未命名管道,则可能仍需要处理此情况.| 归档时间: |
|
| 查看次数: |
9355 次 |
| 最近记录: |