在Windows系统中使用select.select读取sys.stdin

7

可能是重复问题:
在Windows下Python中可以使用select()选择文件吗?

在UNIX上,我能够将sys.stdin传递给Python中的select.select。我正在尝试在Windows上做同样的事情,但是Python在Windows上的select.select不允许这样做。

为了更准确地描述我正在做什么,请参见https://github.com/eldarion/gondor-client/blob/ccbbf9d4b61ecbc2f66f510b993eb5fba0d81c09/gondor/run.py

unix_run_poll函数是我正在尝试在Windows上实现的。基本思路是,我有一个套接字连接到一个服务器,该服务器已将流式标准输入、标准输出、标准错误钩子连接到远程运行的进程,并且我正在从本地客户端与之交互,使其看起来像本地客户端正在运行该进程。

win32_run_poll是我尝试将其移植到Windows的方法,它确实可以工作,但有点不稳定,而且我认为这种做法非常糟糕。

有人有改进建议吗?对win32api的依赖不太理想,但我可以接受保留它。


1
你有没有看过专门用于事件循环实现的库/框架?例如,twisted 有两个 Win32 reactor 的实现。 - user4815162342
很有趣,你提到了那个。我恰好正在做这件事。 :-) - Brian Rosner
另一种可能性是将套接字直接赋予脚本,而不是将其包装为脚本的标准输入/输出,然后您可以使用select.select。 - abarnert
我没有表达好我的问题。作为发布者,我知道在 Windows 上不能在 select 中使用 sys.stdin。你链接的问题正是提供了这个答案。但我不想要那个答案。如果你看一下我提供的代码,就会发现我比我的问题标题所表达的更清楚地理解了这个问题。 - Brian Rosner
1个回答

7
在Windows上,select 仅适用于套接字,并且不适用于任意文件句柄(Windows没有文件描述符的概念)。有关此问题的更多信息,请参见 msdn文档,此问题也在 select 模块的python文档中提到。
如果您想对任意文件使用轮询,则应查找抽象套接字和文件句柄轮询的选项。这可能是评论中提到的twisted反应器,或者是绑定到libuv的python,或者是其他事件库。

1
另一个选择是通过pywin32调用WaitForMultipleObjects - Adam Rosenfield
1
这并不完全准确。Python文档说:“在Windows上,底层的select()函数由WinSock库提供,并且不能处理不起源于WinSock的文件描述符。”但这也不完全准确。正如你所说,Windows没有文件描述符的概念,但是C库(MSVCRT)和WinSock库都有,问题在于它们不是相同的概念。(为了让事情更有趣,现代版本的WinSock实际上不使用select中的文件描述符;fd_set实际上是一个句柄数组...) - abarnert
似乎对于文件句柄,WaitForMultipleObjects / WaitForSingleObject未定义,但它们可用于控制台输入。请参见http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx。 - dnaq
@danvari: 将文件句柄传递给Wait函数将等待直到该文件的下一次I/O完成。如果您拥有一个非重叠的文件句柄,则每次只有一个未完成的I/O,等待可能是有用的。如果您有一个重叠的句柄,则可能存在多个并发I/O,并且仅凭文件句柄无法确定哪个I/O已完成。 - Gabe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接