Позволяет сочетание клавиш CTRL-C для прерывания питона с расширением
Я запускаю некоторое вычислительно тяжелое моделирование в (самодельных) расширениях python на основе C. Иногда я что-то неправильно понимаю и хотел бы прекратить симуляцию. Однако Ctrl-C, похоже, не имеет никакого эффекта (кроме печати ^C на экран, поэтому мне приходится убивать процесс с помощью kill или системного монитора.
Насколько я могу видеть, python просто ждет завершения расширения C и не связывается с ним в течение этого времени.
Есть ли способ сделать эта работа?
3 ответов:
Я бы перепроектировал расширения C, чтобы они не работали в течение длительного периода.
Итак, разбейте их на более простые шаги (каждый выполняется в течение короткого периода времени, например, от 10 до 50 миллисекунд), и пусть эти более простые шаги вызываются кодом Python.
Продолжение стиля передачи может быть уместно понять, как стиль программирования...
Python имеет обработчик сигналов, установленный на
SIGINT, который просто устанавливает флаг, проверяемый главным циклом интерпретатора. Чтобы этот обработчик работал правильно, интерпретатор Python должен выполнять код Python.У вас есть несколько вариантов, доступных для вас:
- использование
Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADSчтобы освободить GIL вокруг вашего кода расширения C. Вы не можете использовать какие-либо функции Python, когда не держите GIL, но код Python (и другой код C) может выполняться одновременно с вашим потоком C (true многопоточный режим). Отдельный поток Python может выполняться вместе с расширением C и перехватывать сигналы Ctrl+C.- настройте свой собственный обработчик
SIGINTи вызовите исходный обработчик сигнала (Python). Ваш обработчикSIGINTможет затем сделать все необходимое, чтобы отменить код расширения C и вернуть управление интерпретатору Python.
Однако Ctrl-C, похоже, не имеет никакого эффекта
Ctrl-Cв оболочке отправляетSIGINTв группу процессов переднего плана .pythonпри приеме сигнала устанавливает флаг в C-коде. Если ваше расширение C работает в основном потоке, то никакой обработчик сигналов Python не будет запущен (и поэтому вы не увидитеKeyboardInterruptисключение наCtrl-C), если вы не вызоветеPyErr_CheckSignals()это проверяет флаг (это означает: он не должен замедлять вас) и запускает обработчики сигналов Python, если это необходимо или если ваше моделирование позволяет выполнять код Python (например, если моделирование использует обратные вызовы Python). Если расширение работает в фоновом потоке, то достаточно выпустить GIL (чтобы позволить Python-коду работать в основном потоке, что позволяет запускать обработчики сигналов).Связанные: Cython, Python и KeybordInterrupt ingored
Comments