8

此之后示例,我正在尝试创建一个简单的接收器。该示例使用无限循环。一切正常。但是,在 MS Windows 上,当我按下 CTRL+C 来引发 KeyboardInterrupt 时,循环不会中断。似乎该recv()方法以某种方式忽略了异常。但是,我很想通过按 CTRL+C 而不是杀死它来退出该过程。那可能吗?

4

4 回答 4

15

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

import signal

signal.signal(signal.SIGINT, signal.SIG_DFL);
# any pyzmq-related code, such as `reply = socket.recv()`
于 2014-10-15T21:53:57.893 回答
3

一个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 代码时;pyzmqrecv()调用在低级 C 代码中显然会阻塞,因此 Python 永远没有机会发出 KeyboardInterrupt。但是如果你使用zmq.Poller它,它会在超时时停止,并让解释器有机会在超时完成后发出 KeyboardInterrupt。

于 2014-01-23T17:00:08.233 回答
2

Don't know if this going to work in Windows, but in Linux I did something like this:

if signal.signal(signal.SIGINT, signal.SIG_DFL):
    sys.exit()
于 2013-06-18T17:56:06.550 回答
1

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

于 2014-03-22T07:56:55.007 回答