Я работаю над проектом, который сочетает в себе высокопроизводительные алгоритмы, написанные на C ++, с интерфейсом Python. Классы и функции C ++ упакованы и доступны Python через компилятор Cython.
Предположим, я вызываю долго работающую нативную функцию из интерпретатора Python (я предпочитаю IPython). Возможно ли каким-то образом прервать или прервать выполнение этого кода, не убивая интерпретатора?
Вот возможная реализация с использованием 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)
остановится изящно с прерыванием клавиатуры.
Хорошо, я предполагаю, что вы пытаетесь запустить какой-то кусок оптимизированного кода, который может столкнуться с проблемами (например, работать дольше, чем ожидалось), а затем вам нужно будет его убить.
Насколько я понимаю, остановка исполняемого кода просто невозможна без уничтожения интерпретатора, так как будет выполняться код C / C ++ из управления виртуальной машиной Python. Таким образом, один из вариантов будет использовать стандарт multiprocessing
Модуль для запуска кода в отдельном процессе.
Это позволит вам беспрепятственно передавать данные вперед и назад. а также это добавило бы возможность убить новый процесс, используя любые стандартные средства, например. Process.terminate
, os.kill
… из родительского процесса; или любую командную строку / графический инструмент, который предоставляет ваша ОС.
Посылка cysignals
решает эту проблему. Увидеть этот ответ.