通过键盘中断停止 pyzmq 接收器

问题描述 投票:0回答:4

按照 ØMQ 文档中的 this 示例,我正在尝试创建一个简单的接收器。该示例使用无限循环。一切都很好。但是,在 MS Windows 上,当我按 CTRL+C 引发 KeyboardInterrupt 时,循环不会中断。似乎

recv()
方法以某种方式忽略了异常。但是,我希望通过按 CTRL+C 退出该进程,而不是终止它。这可能吗?

python loops break termination pyzmq
4个回答
17
投票

为了回应@Cyclone的请求,我建议以下作为可能的解决方案:

import signal
    
signal.signal(signal.SIGINT, signal.SIG_DFL)
# any pyzmq-related code, such as `reply = socket.recv()`

4
投票

一个

zmq.Poller
物体似乎有帮助:

def poll_socket(socket, timetick = 100):
    poller = zmq.Poller()
    poller.register(socket, zmq.POLLIN)
    # wait up to 100msec
    try:
        while True:
            obj = dict(poller.poll(timetick))
            if socket in obj and obj[socket] == zmq.POLLIN:
                yield socket.recv()
    except KeyboardInterrupt:
        pass
    # Escape while loop if there's a keyboard interrupt.

然后你可以做这样的事情:

for message in poll_socket(socket):
    handle_message(message)

并且 for 循环将在 Ctrl-C 上自动终止。看起来从 Ctrl-C 到 Python KeyboardInterrupt 的转换仅在解释器处于活动状态并且 Python 尚未将控制权交给低级 C 代码时才会发生;在低级 C 代码中,pyzmq

recv()
调用显然会阻塞,因此 Python 永远没有机会发出键盘中断。但如果您使用
zmq.Poller
那么它将在超时时停止,并让解释器有机会在超时完成后发出键盘中断。


2
投票

不知道这是否适用于 Windows,但在 Linux 中我做了这样的事情:

if signal.signal(signal.SIGINT, signal.SIG_DFL):
    sys.exit()

1
投票

尝试 ctrl+break (就像上面的 Page Up 键一样,我必须查找它,我想我以前从未碰过该键) 建议靠近此线程的底部。我没有做过任何太花哨的事情,但这似乎在我尝试过的情况下效果很好。

© www.soinside.com 2019 - 2024. All rights reserved.