通过KeyboardInterrupt停止pyzmq接收器

Tre*_*reg 6 python loops termination break pyzmq

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

Tre*_*reg 6

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

import signal

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

  • 这个效果出奇的好,但是怎么样? (2认同)

Jas*_*n S 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.
Run Code Online (Sandbox Code Playgroud)

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

for message in poll_socket(socket):
    handle_message(message)
Run Code Online (Sandbox Code Playgroud)

并且 for 循环将在 Ctrl-C 上自动终止。看起来从 Ctrl-C 到 Python KeyboardInterrupt 的转换仅在解释器处于活动状态并且 Python 尚未将控制权交给低级 C 代码时才会发生;pyzmqrecv()调用在低级 C 代码中显然会阻塞,因此 Python 永远没有机会发出键盘中断。但如果你使用的zmq.Poller话,它将在超时时停止,并让解释器有机会在超时完成后发出键盘中断。

  • 截至今天,我有时仍然被迫终止我的应用程序,而不是按 CTRL+C —— 非常不舒服......我也在使用 `zmq.Poller` (感谢“for..in”模式,顺便说一句。!),但在某些情况下 Poller 没有帮助:1)使用内置设备(`zmq.device()`),2)使用 REQ 套接字以防 REP 工作线程中断。我发现了以下内容:http://zguide.zeromq.org/py:interrupt,但发现没有用处。 (2认同)