3

我希望能够使用通常的 CTRL+C 中断命令用 cython 中断一个长函数。我的 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;

(psself.thisptr是指向当前实现的类的指针aLongFunction()

4

2 回答 2

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等,然后查看特定的特定杀戮信号。(无论如何,请查看python C-Api以获取详细信息......)PyErr_CheckSignals0ExceptionKeybordInterrupt


如果您在 while 循环中调用 cythoncdef函数,您也可以通过添加except *

cdef function(...) except *:
    pass

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

于 2012-11-13T17:29:04.720 回答
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()

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

于 2012-11-12T10:52:03.800 回答