检测命名管道的关闭
Posted
技术标签:
【中文标题】检测命名管道的关闭【英文标题】:Detect close of named pipe 【发布时间】:2015-04-02 03:13:15 【问题描述】:我有一个将数据写入命名管道的 C 程序和一个从命名管道读取数据的 Python 程序,如下所示:
p = open('/path/to/named/pipe', 'r')
...
data = p.read(size)
当 C 程序退出时,它会关闭管道。
如何从 Python 端检测到这一点?我尝试为 SIGPIPE 安装处理程序,但似乎 SIGPIPE 仅在尝试写入封闭管道时发生,而不是从中读取。我还预计 p.read(size)
可能会因为另一端的 EOF 而返回长度为零的字符串,但实际上它只是挂起等待数据。
我该如何检测并处理这种情况?
【问题讨论】:
如果 Python 处于闲置状态,这几乎肯定意味着某个进程(可能它本身)仍然有管道打开以供写入。如果所有的作者都关闭了管道,那么所有的读者(通常,'all' 只是一个读者)将在他们下一次尝试阅读时获得 EOF。请注意,如果 Python 打开管道进行读取和写入,它是一个写入器,永远不会得到 EOF。 您可以为该文件描述符放置nonblock
。
我认为这里的问题是使用open(...,'r')
没有做正确的事情;必须使用os.open(..., os.O_RDONLY)
。
【参考方案1】:
您可以使用the select
module 来监控管道的状态。在 Linux 上(select.poll()
可用,以下代码将检测是否存在封闭管道:
import select
# ...
poller = select.poll()
# Register the "hangup" event on p
poller.register(p, select.POLLHUP)
# Call poller.poll with 0s as timeout
for descriptor, mask in poller.poll(0):
# Can contain at most one element, but still:
if descriptor == p.fileno() and mask & select.POLLHUP:
print('The pipe is closed on the other end.')
p.close()
其他操作系统也有类似的方法可以检测到这种情况。
调用read
时挂起,是因为IO阻塞。您可以使用os.set_blocking
将其变为非阻塞(并让read
返回一个空字符串),但这仍然无法让您检测到另一端的管道何时关闭。
【讨论】:
以上是关于检测命名管道的关闭的主要内容,如果未能解决你的问题,请参考以下文章