Я внедряю интерпретатор Python в программу на C. Однако может случиться, что при запуске какого-либо скрипта python через PyRun_SimpleString()
будет выполняться бесконечный цикл или выполнить слишком долго. Рассмотрим PyRun_SimpleString("while 1: pass");
В предотвращении блокировки основной программы я думал, что могу запустить интерпретатор в потоке.Остановка встроенного Python
Как прекратить выполнение скрипта python во встроенном интерпретаторе, запущенном в потоке, не убивая весь процесс?
Можно ли передать исключение интерпретатору? Должен ли я обернуть скрипт под другим скриптом, который будет слушать сигналы?
PS: Я мог бы запустить питона в отдельном процессе, но это не то, что я хочу - если это не последняя инстанция ...
Update:
Итак, это работает сейчас. Спасибо, Денис Откидах, еще раз!
Если я вижу это правильно, вам нужно сделать две вещи: сказать интерпретатору остановиться и return -1
в том же потоке, что и ваш PyRun_SimpleString().
Чтобы остановиться, у вас есть несколько возможностей: PyErr_SetString(PyExc_KeyboardInterrupt, "...")
или PyErr_SetInterrupt()
- первый может оставить Python еще несколько инструкций, а затем он остановится, а затем он немедленно прекратит выполнение.
К return -1
вы используете Py_AddPendingCall()
для ввода вызова функции в выполнение Python. Документы упоминают его с версии 2.7 и 3.1, но он работает и с более ранними Pythons (здесь 2.6). Начиная с 2.7 и 3.1, он также должен быть потокобезопасным, то есть вы можете назвать его, не приобретая GIL (?).
Так можно переписать пример ниже:
int quit() {
PyErr_SetInterrupt();
return -1;
}
Этот вид * очень * интересный, но не для самого нового Python? (2,7 альфа вышла только сегодня.) Однако я мог бы перейти на Python 3.1 - но что тогда? Какую функцию я должен зарегистрировать через 'Py_AddPendingCall()'? 'PyErr_SetString()'? 'Py_Exit()'? 'Py_Finalize()'? –
Py_AddPendingCall существует, по крайней мере, из python 2.0 (определен в ceval.h).Я добавил пример кода к моему ответу. –
Спасибо! Оно работает! –