通过KeyboardInterrupt停止pyzmq接收器

时间:2013-06-18 16:19:14

标签: python loops break termination pyzmq

在ØMQ文档中的this示例之后,我正在尝试创建一个简单的接收器。该示例使用无限循环。一切正常。但是,在MS Windows上,当我按CTRL + C来引发KeyboardInterrupt时,循环不会中断。似乎recv()方法忽略了异常。但是,我喜欢通过点击CTRL + C而不是杀死它来退出该过程。这可能吗?

4 个答案:

答案 0 :(得分:6)

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

import signal

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

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上终止。看起来只有当解释器处于活动状态并且Python没有对低级C代码进行控制时,才会发生从Ctrl-C到Python KeyboardInterrupt的转换。在低级C代码中,pyzmq recv()调用显然会阻塞,因此Python永远不会有机会发出KeyboardInterrupt。但是如果你使用zmq.Poller那么它将在超时时停止,并在解除超时后让解释器有机会发出KeyboardInterrupt。

答案 3 :(得分:1)

尝试ctrl + break(如在Page Up上面的键中,我必须查找它,我不认为我之前曾经触过那个键) 建议在this thread的底部附近。我没有做过任何过于花哨的事情,但在我尝试的情况下,这似乎运作良好。