Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通过键盘中断停止pyzmq接收器_Python_Loops_Break_Termination_Pyzmq - Fatal编程技术网

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

Python 通过键盘中断停止pyzmq接收器,python,loops,break,termination,pyzmq,Python,Loops,Break,Termination,Pyzmq,下面是ØMQ文档中的示例,我试图创建一个简单的接收器。该示例使用无限循环。一切正常。但是,在MS Windows上,当我按CTRL+C键以引发键盘中断时,循环不会中断。似乎recv()方法忽略了异常。但是,我希望通过点击CTRL+C退出进程,而不是终止它。这可能吗?不知道这在Windows中是否可行,但在Linux中,我做了如下操作: if signal.signal(signal.SIGINT, signal.SIG_DFL): sys.exit() 一个zmq.Poller对象似乎

下面是ØMQ文档中的示例,我试图创建一个简单的接收器。该示例使用无限循环。一切正常。但是,在MS Windows上,当我按CTRL+C键以引发键盘中断时,循环不会中断。似乎
recv()
方法忽略了异常。但是,我希望通过点击CTRL+C退出进程,而不是终止它。这可能吗?

不知道这在Windows中是否可行,但在Linux中,我做了如下操作:

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

一个
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键盘中断的转换只有在解释器处于活动状态且Python没有将控制权让给低级C代码时才会发生;pyzmq
recv()
调用显然会在低级C代码中阻塞,因此Python从来没有机会发出键盘中断。但是,如果您使用
zmq.Poller
,它将在超时时停止,并给解释器一个在超时完成后发出键盘中断的机会。

尝试ctrl+break(就像上面页面中的键一样,我必须查找它,我想我以前从未触摸过该键)
建议在底部附近。我没有做任何太花哨的事情,但在我尝试过的案例中,这似乎足够有效。

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

import signal

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

这对我来说并不适用,
sys.exit()
总是被调用——在文档中,我发现
signal.signal(…)
只设置信号处理程序。但是,放入
signal.signal(signal.SIGINT,signal.SIG_-DFL)在无限循环解决我的问题之前,现在可以使用CTRL+C终止接收器!所以非常感谢你的提示@Tregoreg,你应该发表你的评论作为回答。我会投票表决。。。这对我来说很有用,而且比更改代码处理请求的方式干净多了。@Cyclone感谢您的反馈,我按照您的建议做了。到今天为止,我仍然有时被迫终止应用程序而不是按CTRL+C键--非常不舒服。。。我也在使用
zmq.Poller
(感谢“for..in”模式,顺便说一句!),但有些情况下,Poller没有帮助:1)使用内置设备(
zmq.device()
),2)在REP worker中断时使用REQ套接字。我发现如下:,但没有发现它的用处。卓越。这对我很有用(Windows10)。尚未尝试接受的答案,但您似乎也在使用此解决方案。