#c #python #api #profile #execution
#c #python #API #Профиль #выполнение
Вопрос:
1) Я хотел бы использовать функции профилирования в Python C API, чтобы перехватывать интерпретатор python, когда он возвращается из определенных функций.
2) Я хотел бы приостановить интерпретатор python, отправить выполнение обратно функции, которая вызвала интерпретатор в моей программе C , и, наконец, вернуть выполнение интерпретатору python, запустив его в строке кода после того, как оно остановилось. Я хотел бы поддерживать как глобальные, так и локальные значения между моментами, когда выполнение принадлежит python.
Часть 1 я закончил. Часть 2 — это мой вопрос. Я не знаю, что сохранить, чтобы я мог вернуться к выполнению, или как вернуться к выполнению, учитывая эти сохраненные данные.
Из того, что я смог найти в документах python API, мне придется сохранить некоторую часть исполняемого фрейма, но я ничего не нашел. Некоторые дополнительные вопросы… Что именно содержит PyFrameObject? Удивительно, но документы python API никогда не объясняют этого.
Комментарии:
1. Вы пробовали посмотреть на использование
SIGSTOP
/SIGCONT
?2. Мой интерпретатор Python запущен в том же потоке, что и моя программа на C … Я хочу, чтобы выполнение передавалось в этом потоке, а не останавливало весь процесс… Возможно, я не до конца понимаю, какое влияние SIGSTOP и SIGCONT окажут на мою программу? Если да, пожалуйста, объясните.
Ответ №1:
Если я понимаю вашу проблему, у вас есть программа на C , которая вызывает python. Когда python завершает выполнение функции, вы хотите приостановить интерпретатор и продолжить с того места, на котором остановился код C . Некоторое время спустя вашей программе на C необходимо вернуться к python и попросить интерпретатор python продолжить с того места, на котором она остановилась.
Я не думаю, что вы можете сделать это очень легко с помощью одного потока. Перед приостановкой интерпретатора стек выглядит следующим образом:
[ top of stack ]
[ some interpreter frames ]
[ some c frames ]
Чтобы приостановить интерпретатор, вам нужно сохранить фреймы интерпретатора и вернуться к самому верхнему фрейму C . Затем, чтобы отменить паузу, вам нужно восстановить фреймы интерпретатора и перейти вверх по стеку к тому месту, где вы остановились. Переключение выполнимо (см. http://en.wikipedia.org/wiki/Setjmp.h ), но сохранить и восстановить стек сложнее. Я не знаю API для этого.
Однако вы могли бы сделать это с помощью двух потоков. Поток, созданный в начале вашей программы на c (назовем его потоком 1), запускает код на c и создает поток 2 для запуска интерпретатора python.
Изначально (при запуске кода c ) выполняется поток 1, а поток 2 заблокирован (скажем, в переменной условия, см.https://computing.llnl.gov/tutorials/pthreads /). Когда вы запускаете или отменяете паузу, поток интерпретатора 1 сигнализирует о переменной условия и ожидает ее. Это приводит к пробуждению потока 2 (который запускает интерпретатор) и вызывает блокировку потока 1. Когда интерпретатору необходимо сделать паузу, поток 2 сигнализирует о переменной условия и ожидает ее (таким образом, поток 2 блокируется, поток 1 пробуждается). Вы можете переключаться между потоками сколько душе угодно. Надеюсь, это поможет.
Комментарии:
1. Спасибо! Я только что погуглил вокабуляр в вашем ответе, который я не понял, так что теперь я понимаю, что вы имеете в виду. Сработало как по волшебству.