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

发布于 2024-12-10 17:08:58 字数 362 浏览 1 评论 0原文

1)我想使用Python C API中的分析函数来捕获Python解释器从特定函数返回时的情况。

2)我想暂停python解释器,将执行发送回在我的C++程序中调用解释器的函数,最后将执行返回到python解释器,在停止后的代码行上启动它。我想在执行属于 python 的时间之间维护全局变量和局部变量。

第 1 部分我已经完成了。第 2 部分是我的问题。我不知道要保存什么以便可以返回执行,也不知道如何根据保存的数据返回执行。

从我可以从 python API 文档中得到的内容来看,我必须保存执行框架的某些部分,但我还没有找到任何东西。一些附加问题... PyFrameObject 到底包含什么?令人惊讶的是,Python API 文档从未解释过这一点。

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.

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. I would like to maintain both globals and locals between the times where execution belongs to python.

Part 1 I've finished. Part 2 is my question. 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. Some additional questions...
What, exactly does a PyFrameObject contain? The python API docs, surprisingly, never explain that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

跨年 2024-12-17 17:08:58

如果我理解你的问题,你有一个调用 python 的 C++ 程序。当 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 唤醒)。您可以随心所欲地在线程之间来回切换。希望这有帮助。

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 ] 

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.

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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文