Python 通过键盘中断停止pyzmq接收器
下面是ØMQ文档中的示例,我试图创建一个简单的接收器。该示例使用无限循环。一切正常。但是,在MS Windows上,当我按CTRL+C键以引发键盘中断时,循环不会中断。似乎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对象似乎
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代码时才会发生;pyzmqrecv()
调用显然会在低级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)。尚未尝试接受的答案,但您似乎也在使用此解决方案。