【问题标题】:Interrupting Select to add another socket to watch in Python中断 Select 以添加另一个套接字以在 Python 中观看
【发布时间】:2011-01-11 17:45:47
【问题描述】:

我正在 Windows XP 应用程序中使用 TCP 实现对等 IPC。

我在 Python 2.6.6 中使用 selectsocket 模块。

我有三个 TCP 线程,一个通常在 select() 上阻塞的读取线程,一个通常等待事件的写入线程(该事件表明有东西要写入 TCP)和一个接受连接的侦听线程.

如果我开始一个新连接或关闭一个当前连接,那么我需要中断读取选择并重新启动它,以便它也侦听新接受的套接字。

winsock 下,我可以调用WSACancelBlockingCall,这将优雅地中断选择。

所以我的问题是:是否可以在不使用poll() 的情况下以pythonic 方式完成所有这些操作?

谢谢

--DM

【问题讨论】:

  • 我不确定我是否理解 poll 与 select 有何不同 - 它们都需要超时。 Select 可以无限期地等待。两者都可以立即返回。无论我使用哪个,如果我在不同的线程上接受一个新的套接字,我仍然需要打破等待。

标签: python tcp winsock


【解决方案1】:

您可以尝试在您的集合中添加一个额外的文件描述符,用作信号机制。然后,您可以向该描述符写入一个虚拟值以使select 退出。例如:

my_pipe = os.pipe()
...
while True:
    ready_fds = select.select(my_read_fds + [my_pipe[0]],
                              my_write_fds, my_except_fds, timeout)
    if my_pipe[0] in ready_fds[0]:
        # Add another fd to my_read_fds, etc.
        os.read(my_pipe[0], 1)
    ...

# To interrupt the current select call and add a new fd, write to the pipe:
os.write(my_pipe[1], 'x')

【讨论】:

  • 很好的答案。但这仅适用于unix。在 Windows 下 select 仅适用于 winsock 句柄。鉴于您的建议,我猜测由于 winsock 的这种限制,我实际上需要调用 WSACancelBlockingCall。
【解决方案2】:

我无法添加 cmets,因此我将其添加为答案。

不要使用WSACancelBlockingCall。您应该使用 Adam Rosenfield 的 answer 中的方法。只需将一对虚拟套接字连接到另一个,而不是虚拟文件描述符。在您的 select() 调用中包含其中一个套接字。当您需要中断呼叫时 - 只需将一个字节写入第二个虚拟套接字。

哦,当select() 将返回时,不要忘记从第一个套接字中读取该字节。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-19
    • 2021-01-15
    • 1970-01-01
    • 2019-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    相关资源
    最近更新 更多