问题描述
我目前正在使用Twisted在回调内的for循环中重复执行任务,但是如果用户通过Ctrl-C发出KeyboardInterrupt,我希望反应堆中断回调中的循环(一个).根据我的测试,反应堆仅在回调结束时停止或处理中断.
I'm currently repeating a task in a for loop inside a callback using Twisted, but would like the reactor to break the loop in the callback (one) if the user issues a KeyboardInterrupt via Ctrl-C. From what I have tested, the reactor only stops or processes interrupts at the end of the callback.
在回调运行的中间,有什么方法可以发送KeyboardInterrupt到回调或错误处理程序吗?
Is there any way of sending a KeyboardInterrupt to the callback or the error handler in the middle of the callback run?
干杯
克里斯
#!/usr/bin/env python
from twisted.internet import reactor, defer
def one(result):
print "Start one()"
for i in xrange(10000):
print i
print "End one()"
reactor.stop()
def oneErrorHandler(failure):
print failure
print "INTERRUPTING one()"
reactor.stop()
if __name__ == '__main__':
d = defer.Deferred()
d.addCallback(one)
d.addErrback(oneErrorHandler)
reactor.callLater(1, d.callback, 'result')
print "STARTING REACTOR..."
try:
reactor.run()
except KeyboardInterrupt:
print "Interrupted by keyboard. Exiting."
reactor.stop()
推荐答案
这是为了避免(半)抢占,因为Twisted是协作式多任务处理系统. Ctrl-C在Python中使用解释器在启动时安装的SIGINT处理程序进行处理.处理程序在调用时设置一个标志.执行完每个字节代码后,解释器将检查该标志.如果已设置,则此时会引发KeyboardInterrupt.
This is intentional to avoid (semi-)preemption, since Twisted is a cooperative multitasking system. Ctrl-C is handled in Python with a SIGINT handler installed by the interpreter at startup. The handler sets a flag when it is invoked. After each byte code is executed, the interpreter checks the flag. If it is set, KeyboardInterrupt is raised at that point.
反应堆安装自己的SIGINT处理程序.这代替了解释程序处理程序的行为.反应堆的处理程序启动反应堆关闭.由于它不会引发异常,因此它不会中断正在运行的任何代码.循环(或其他任何循环)完成,当控制权返回到反应堆时,关机继续进行.
The reactor installs its own SIGINT handler. This replaces the behavior of the interpreter's handler. The reactor's handler initiates reactor shutdown. Since it doesn't raise an exception, it doesn't interrupt whatever code is running. The loop (or whatever) gets to finish, and when control is returned to the reactor, shutdown proceeds.
如果您希望Ctrl-C(即SIGINT)提高KeyboardInterrupt,那么您可以使用信号模块来恢复Python的SIGINT处理程序:
If you'd rather have Ctrl-C (ie SIGINT) raise KeyboardInterrupt, then you can just restore Python's SIGINT handler using the signal module:
signal.signal(signal.SIGINT, signal.default_int_handler)
但是,请注意,如果在运行Twisted的代码而不是您自己的应用程序代码时发送SIGINT,则该行为是不确定的,因为Twisted不会被KeyboardInterrupt中断.
Note, however, that if you send a SIGINT while code from Twisted is running, rather than your own application code, the behavior is undefined, as Twisted does not expect to be interrupted by KeyboardInterrupt.
这篇关于扭曲-通过KeyboardInterrupt中断回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!