【发布时间】:2019-04-10 08:41:32
【问题描述】:
我的应用程序将数据流式传输(写入)到命名管道,在调用应用程序时将管道名称指定为 CLI 参数。流数据是不规则的,其中可能没有任何数据可以通过管道发送。
我想检测从管道读取的其他进程何时结束,以便快速释放我的应用程序为流式传输分配的资源。我现在的问题是甚至检测到管道的读取端已经关闭,而没有向管道中写入任何内容。
由于流数据格式是固定的并且不允许空写入或 ping,即使我没有要流式传输的内容,我也不能简单地尝试写入一些管道数据以查看管道读取器是否仍在读取。
我在 Linux 上有一个可行的解决方案,不幸的是它在 Windows 上不起作用,因为 Windows 命名管道不能像在 Linux 上一样在 select() 中统一处理。在 Linux 上,我只需检查管道的写入端是否可以读取,因为这表示管道错误,然后关闭管道并释放我分配的资源。
在 Windows 上,这是不可能的。我已经打开了这样写的管道:
fifo = open('//./pipe/somepipe', 'wb')
从管道尝试fifo.read() 不起作用(正如预期的那样)并立即抛出OSException。
正如我所说,我不能尝试一些空/nul 写入; fifo.write(b'') 什么都不做,甚至根本不戳管道以获得可写性。
在 Windows 上是否有任何方法可以测试命名管道的写入端以查看读取器(客户端)是否仍然连接?
【问题讨论】:
-
我假设您在 Windows 中打开“//./pipe/
”。无论如何,如果您直接调用 WINAPI WriteFile,您的想法就会奏效。如果管道正在关闭,这将失败并显示ERROR_NO_DATA(232)。 -
另外,如果你熟悉NT API,你可以直接查询这个,不用空写。致电
NtQueryInformationFile获取FilePipeLocalInformation。 Pythonopen(特别是 WINAPICreateFile)总是请求读取属性访问,因此即使它是入站管道(即客户端只有写入数据访问权限),我们也可以在客户端读取此信息。NamedPipeState将是FILE_PIPE_CLOSING_STATE(4)。 -
@eryksun:听起来很有趣,会试试这个;目前我找到了一种解决方法,即外部应用程序协议有一个扩展点,我可以通过编写一个特殊记录来重用它来检查管道状态,接收应用程序会默默地忽略它。
标签: python windows named-pipes