Python C API - Остановить выполнение (и продолжить его позже) - PullRequest
3 голосов
/ 18 октября 2011

1) Я хотел бы использовать функции профилирования в Python C API, чтобы поймать интерпретатор python, когда он возвращается из определенных функций.

2) Я хотел бы приостановить интерпретатор python, отправить выполнение обратно функции, которая вызвала интерпретатор в моей программе на C ++, и, наконец, вернуть выполнение интерпретатору python, запустив его в строке кода после того места, где он остановился. Я хотел бы сохранить и глобальные и локальные между временами, когда выполнение принадлежит Python.

Часть 1 Я закончил. Часть 2 мой вопрос. Я не знаю, что сохранить, чтобы я мог вернуться к выполнению или как вернуться к выполнению, если эти сохраненные данные.

Из того, что я мог получить из документации по Python API, мне придется сохранить некоторую часть исполняемого фрейма, но я ничего не нашел. Некоторые дополнительные вопросы ... Что именно содержит PyFrameObject? Удивительно, но документы Python API никогда не объясняют этого.

1 Ответ

2 голосов
/ 05 ноября 2011

Если я понимаю вашу проблему, у вас есть программа на 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 ++ (назовите его thread 1), выполняет код на языке c ++ и создает поток 2 для запуска интерпретатора python.

Первоначально (когда выполнялся код c ++), поток 1 выполняется, а поток 2 блокируется (скажем, по условной переменной, см. https://computing.llnl.gov/tutorials/pthreads/). Когда вы запускаете или отключаете интерпретатор, поток 1 сигнализирует переменную условия, и ожидает его. Это вызывает поток 2 (который запускает интерпретатор) и вызывает блокировку потока 1. Когда интерпретатору необходимо сделать паузу, поток 2 сигнализирует переменную условия и ожидает ее (таким образом, поток 2 блокирует, поток 1 активируется) . Вы можете подпрыгивать от темы к содержанию вашего сердца. Надеюсь, это поможет.

...