且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-04-23 06:09:44

如果我理解你的问题,你就有一个调用 python 的 C++ 程序.当 python 完成一个函数的执行时,你想暂停解释器并从 C++ 代码停止的地方开始.一段时间后,您的 C++ 程序需要重新调用 python,并让 python 解释器从停止的地方开始.

If I understand your problem, you have a C++ program that calls into python. When python finishes executing a function, you want to pause the interpreter and pick up where the C++ code left off. Some time later your C++ program needs to cal back into python, and have the python interpreter pick up where it left off.

我不认为您可以通过一个线程轻松完成此操作.在暂停解释器之前,堆栈看起来像这样:

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 ] 

要暂停解释器,您需要保存解释器框架,并跳回到最顶层的 C++ 框架.然后要取消暂停,您需要恢复解释器帧,并将堆栈跳到您停止的位置.跳跃是可行的(参见 http://en.wikipedia.org/wiki/Setjmp.h),但保存和恢复堆栈更难.我不知道有什么 API 可以做到这一点.

To pause the interpreter, you need to save off the interpreter frames, and jump back to the top-most C++ frame. 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. I don't know of an API to do this.

但是你可以用两个线程来做到这一点.在 c++ 程序开始时创建的线程(称为线程 1)运行 c++ 代码,并创建线程 2 来运行 python 解释器.

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 正在执行,线程 2 被阻塞(例如在条件变量上,请参阅 https://computing.llnl.gov/tutorials/pthreads/).当您运行或取消暂停解释器线程 1 信号条件变量,并等待它.这会唤醒线程 2(运行解释器)并导致线程 1 阻塞.当解释器需要暂停时,线程 2 向条件变量发出信号并等待它(因此线程 2 阻塞,线程 1 唤醒).您可以在线程之间来回弹跳以达到心满意足的程度.希望这会有所帮助.

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/). When you run or unpause the interpreter thread 1 signals the condition variable, and waits on it. This wakes up thread 2 (which runs the interpreter) and causes thread 1 to block. When the interpreter needs to pause, thread 2 signals the condition variable and waits on it (so thread 2 blocks, thread 1 wakes up). You can bounce back and forth between the threads to your heart's content. Hope this helps.