Как прервать собственный код расширения, не убивая интерпретатор?

Я работаю над проектом, который сочетает в себе высокопроизводительные алгоритмы, написанные на C ++, с интерфейсом Python. Классы и функции C ++ упакованы и доступны Python через компилятор Cython.

Предположим, я вызываю долго работающую нативную функцию из интерпретатора Python (я предпочитаю IPython). Возможно ли каким-то образом прервать или прервать выполнение этого кода, не убивая интерпретатора?

2

Решение

Вот возможная реализация с использованием multiprocessing как предположил Рикардо С.,

import multiprocessing as mpr
def dangerwrap(f):
"""I assume f is, or eventually calls,
some external function, like cython wrapped C/C++.
Also assuming that f returns an
object and takes no parameters
"""event  = mpr.Event()
q = mpr.Queue()

def signalling_f():
q.put(f())
event.set()

f_process = mpr.Process(target = signalling_f)
f_process.start()
try:
event.wait()

except KeyboardInterrupt:
f_process.terminate()
f_process.join()
print "Caught in dangerwrap"return Noneprint "Exiting normally"return q.get()

Теперь вместо

X = f()

который не будет отвечать на прерывания клавиатуры, вызывая

X = dangerwrap(f)

остановится изящно с прерыванием клавиатуры.

2

Другие решения

Хорошо, я предполагаю, что вы пытаетесь запустить какой-то кусок оптимизированного кода, который может столкнуться с проблемами (например, работать дольше, чем ожидалось), а затем вам нужно будет его убить.

Насколько я понимаю, остановка исполняемого кода просто невозможна без уничтожения интерпретатора, так как будет выполняться код C / C ++ из управления виртуальной машиной Python. Таким образом, один из вариантов будет использовать стандарт multiprocessing Модуль для запуска кода в отдельном процессе.

Это позволит вам беспрепятственно передавать данные вперед и назад. а также это добавило бы возможность убить новый процесс, используя любые стандартные средства, например. Process.terminate, os.kill… из родительского процесса; или любую командную строку / графический инструмент, который предоставляет ваша ОС.

1

Посылка cysignals решает эту проблему. Увидеть этот ответ.

0
По вопросам рекламы [email protected]