在Cython中用键盘中断`while循环`

时间:2012-11-12 10:22:00

标签: c++ python interrupt cython keyboard-events

我希望能够使用通常的CTRL + C中断命令使用cython中断long函数。 我的C ++ long函数在Cython代码的while循环中重复调用,但我希望能够在循环期间发送“中断”并阻止while循环。

中断也应该等待longFunction()完​​成,这样就不会丢失数据或保持未知状态。

这是我的第一个实现之一,显然不起作用:

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;

(p。self.thisptr是指向当前类的指针,它实现aLongFunction()

2 个答案:

答案 0 :(得分:0)

你应该可以这样做:

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()

您还可以使用其他变量来跟踪计算是否被手动中止。

答案 1 :(得分:0)

我不是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

当然这不是异步,这可能是可能的,但我不知道,这打破了任何信号的循环,而不仅仅是Ctrl + C.也许最好不要在每次循环迭代中检查信号,至少如果做的很便宜。

如果PyErr_Occurred未返回PyErr_CheckSignals,您可以致电0等,并查看Exception提出哪些专门用于KeybordInterrupt或某些杀戮信号。 (无论如何,请查看python C-Api以获取详细信息......)


如果你在while循环中调用cython cdef函数,如果你添加except *,你也可以实现这个功能:

cdef function(...) except *:
    pass

另见http://docs.cython.org/src/userguide/language_basics.html#error-return-values