[英]Interrupting `while loop` with keyboard in Cython
I want to be able to interrupt a long function with cython, using the usual CTRL+C interrupt command. 我希望能够使用通常的CTRL + C中断命令使用cython中断长函数。 My C++ long function is repeatedly called inside a while loop from Cython code, but I want to be able, during the loop, to send an "interrupt" and block the while loop.
我的C ++ long函数在Cython代码的while循环中重复调用,但我希望能够在循环期间发送“中断”并阻止while循环。
The interrupt also should wait the longFunction() to finish, so that no data are lost or kept in unknown status. 中断也应该等待longFunction()完成,这样就不会丢失数据或保持未知状态。
This is one of my first implementation, which obviously doesn't work: 这是我的第一个实现之一,显然不起作用:
computed=0;
print "Computing long function..."
while ( computed==0 ):
try:
computed = self.thisptr.aLongFunction()
except (KeyboardInterrupt, SystemExit):
computed=1
print '\n! Received keyboard interrupt.\n'
break;
(ps self.thisptr
is the pointer to the current class which implements aLongFunction()
) (ps
self.thisptr
是指向实现aLongFunction()
的当前类的指针)
You should be able to do something like this: 你应该可以做这样的事情:
import signal
class Test():
def __init__(self):
self.loop_finished = False
signal.signal(signal.SIGINT, self.abort_loop)
def abort_loop(self, signal, frame):
self.loop_finished = True
def go(self):
while not self.loop_finished:
print "Calculating"
# Do your calculations
# Once calcations are done, set self.loop_finished to True
print "Calculating over"
Test().go()
You can also use additional variables to keep track of whether the computation was manually aborted or not. 您还可以使用其他变量来跟踪计算是否手动中止。
I am not a Python C-Api foo master, however this works, but maybe its not the best way: 我不是Python C-Api foo大师,但这可行,但也许它不是最好的方法:
cdef extern from "Python.h":
int PyErr_CheckSignals()
def test_interrupt():
cdef int i = 0
while i < 9999999999 and not PyErr_CheckSignals():
# do fancy stuff.
i += 1
Of course that is not asynchronous which is maybe possible but I do not know and this breaks the loop for any signal, not just Ctrl+C. 当然这不是异步,这可能是可能的,但我不知道,这打破了任何信号的循环,而不仅仅是Ctrl + C. Also maybe its better to not check signals every loop iteration, at least if what is done is very cheap.
也许最好不要在每次循环迭代中检查信号,至少如果做的是非常便宜的话。
You could call PyErr_Occurred
, etc. if PyErr_CheckSignals
did not return 0
and see what kind of Exception
got raised to go specifically for KeybordInterrupt
or certain kill signals. 你可以调用
PyErr_Occurred
等,如果PyErr_CheckSignals
没有返回0
,看看有什么样的Exception
被提出专门用于KeybordInterrupt
或某些kill信号。 (Anyway, check the python C-Api for details there...) (无论如何,检查python C-Api的详细信息......)
If you are calling a cython cdef
function inside the while loop you may be able to achieve this also if you add except *
: 如果你在while循环中调用cython
cdef
函数,你可能也可以实现这个,如果你添加except *
:
cdef function(...) except *:
pass
see also http://docs.cython.org/src/userguide/language_basics.html#error-return-values 另见http://docs.cython.org/src/userguide/language_basics.html#error-return-values
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.