gpt4 book ai didi

来自 C++ 应用程序的 Python C API - 知道何时锁定

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:00:32 30 4
gpt4 key购买 nike

我正在尝试编写一个 C++ 类,它调用一个类的 Python 方法,该类同时执行一些 I/O 操作(文件、标准输出)。我遇到的问题是我的类是从不同的线程调用的:有时是主线程,有时是其他线程。显然,我尝试在多线程 native 应用程序中应用 Python 调用的方法。基本上一切都从 PyEval_AcquireLock 和 PyEval_ReleaseLock 或只是全局锁开始。根据文档here当一个线程已经被锁定时,就会发生死锁。当从主线程或其他阻止 Python 执行的线程调用我的类时,我遇到了死锁。

Python> Cfunc1() - C++ func,它在内部创建线程,导致调用“我的类”,它停留在 PyEval_AcquireLock 上,显然 Python 已经被锁定,即等待 C++ Cfunc1 调用完成……如果我省略这些锁,它会很好地完成。当 Python 解释器准备好接受下一个用户命令时,它也能正常完成,即当线程在后台调用函数时——而不是在 native 调用中

我正在寻找解决方法。我需要区分是否允许全局锁定,即 Python 未锁定并准备好接收下一个命令...我尝试了 PyGIL_Ensure,不幸的是我看到挂起。

任何已知的 API 或解决方案?

( python 2.4)

最佳答案

除非您非常特殊地包装了您的 C++ 代码,否则当任何 Python 线程调用您的 C++ 代码时,GIL 保持。您可以在您的 C++ 代码中发布它(如果您想执行一些不需要任何 Python 交互的消耗性任务),然后当您想要进行任何 Python 交互时必须再次获取它-- 参见 the docs : 如果你只是使用旧的 C API,有宏,推荐的习惯用法是

Py_BEGIN_ALLOW_THREADS
...Do some blocking I/O operation...
Py_END_ALLOW_THREADS

文档解释:

The Py_BEGIN_ALLOW_THREADS macro opens a new block and declares a hidden local variable; the Py_END_ALLOW_THREADS macro closes the block. Another advantage of using these two macros is that when Python is compiled without thread support, they are defined empty, thus saving the thread state and GIL manipulations.

因此,在明确发布 GIL(最好是使用该宏)之前,您不必(也不应该)获取 GIL并且需要以任何方式与 Python 交互再次。 (在文档中说“一些阻塞 I/O 操作”的地方,它实际上可能是任何长时间运行的操作,没有任何 Python 交互)。

关于来自 C++ 应用程序的 Python C API - 知道何时锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2986547/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com