简体   繁体   English

Python C API - 停止执行(稍后继续执行)

[英]Python C API - Stopping Execution (and continuing it later)

1) I would like to use the profiling functions in the Python C API to catch the python interpreter when it returns from specific functions. 1)我想使用Python C API中的分析函数来捕获从特定函数返回的python解释器。

2) I would like to pause the python interpreter, send execution back to the function that called the interpreter in my C++ program, and finally return execution to the python interpreter, starting it on the line of code after where it stopped. 2)我想暂停python解释器,将执行发送回在我的C ++程序中调用解释器的函数,最后将执行返回到python解释器,在它停止后的代码行上启动它。 I would like to maintain both globals and locals between the times where execution belongs to python. 我想在执行属于python的时间之间维护全局变量和本地变量。

Part 1 I've finished. 第1部分我已经完成了。 Part 2 is my question. 第2部分是我的问题。 I don't know what to save so I can return to execution, or how to return to execution given that saved data. 我不知道要保存什么,所以我可以返回执行,或者如果保存数据,如何返回执行。

From what I could get off the python API docs, I will have to save some part of the executing frame, but I haven't found anything. 从我可以从python API文档中获取,我将不得不保存执行帧的一些部分,但我还没有找到任何东西。 Some additional questions... What, exactly does a PyFrameObject contain? 一些额外的问题...... PyFrameObject究竟包含什么? The python API docs, surprisingly, never explain that. 令人惊讶的是,python API文档从未解释过。

If I understand your problem, you have a C++ program that calls into python. 如果我理解你的问题,你有一个调用python的C ++程序。 When python finishes executing a function, you want to pause the interpreter and pick up where the C++ code left off. 当python完成一个函数的执行时,你想暂停解释器并获取C ++代码所在的位置。 Some time later your C++ program needs to cal back into python, and have the python interpreter pick up where it left off. 一段时间后,你的C ++程序需要重新调用python,让python解释器从中断处继续。

I don't think you can do this very easily with one thread. 我不认为你可以用一个线程很容易地做到这一点。 Before you pause the interpreter the stack looks like this: 在暂停解释器之前,堆栈如下所示:

[ top of stack ]
[ some interpreter frames ]
[ some c++ frames ] 

To pause the interpreter, you need to save off the interpreter frames, and jump back to the top-most C++ frame. 要暂停解释器,您需要保存解释器帧,然后跳回到最顶层的C ++帧。 Then to unpause, you need to restore the interpreter frames, and jump up the stack to where you left off. 然后要取消暂停,您需要恢复解释器帧,并将堆栈跳到您离开的位置。 Jumping is doable (see http://en.wikipedia.org/wiki/Setjmp.h ), but saving and restoring the stack is harder. 跳跃是可行的(参见http://en.wikipedia.org/wiki/Setjmp.h ),但保存和恢复堆栈更难。 I don't know of an API to do this. 我不知道有这样做的API。

However you could do this with two threads. 但是你可以用两个线程做到这一点。 The thread created at the start of your c++ program (call it thread 1) runs the c++ code, and it creates thread 2 to run the python interpreter. 在c ++程序开始时创建的线程(称为线程1)运行c ++代码,它创建线程2来运行python解释器。

Initially (when were running c++ code), thread 1 is executing and thread 2 is blocked (say on a condition variable, see https://computing.llnl.gov/tutorials/pthreads/ ). 最初(当运行c ++代码时),线程1正在执行,线程2被阻塞(比如在条件变量上,请参阅https://computing.llnl.gov/tutorials/pthreads/ )。 When you run or unpause the interpreter thread 1 signals the condition variable, and waits on it. 当您运行或取消暂停解释器线程1发出条件变量信号并等待它时。 This wakes up thread 2 (which runs the interpreter) and causes thread 1 to block. 这会唤醒线程2(运行解释器)并导致线程1阻塞。 When the interpreter needs to pause, thread 2 signals the condition variable and waits on it (so thread 2 blocks, thread 1 wakes up). 当解释器需要暂停时,线程2发出条件变量的信号并等待它(因此线程2阻塞,线程1唤醒)。 You can bounce back and forth between the threads to your heart's content. 你可以在线程之间来回反复到你内心的内容。 Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM