3

通常の CTRL+C 割り込みコマンドを使用して、cython で長い関数を中断できるようにしたいと考えています。私の C++ long 関数は、Cython コードから while ループ内で繰り返し呼び出されますが、ループ中に「割り込み」を送信して while ループをブロックできるようにしたいと考えています。

また、割り込みは longFunction() が終了するのを待つ必要があるため、データが失われたり、不明な状態のままになったりすることはありません。

これは私の最初の実装の 1 つであり、明らかに機能しません。

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 に答える