在 C++ 代码中发布 Python GIL

Posted

技术标签:

【中文标题】在 C++ 代码中发布 Python GIL【英文标题】:Releasing Python GIL while in C++ code 【发布时间】:2009-10-16 08:07:48 【问题描述】:

我有一个用 C++ 编写的库,我使用 SWIG 包装并在 python 中使用。通常只有一个类,方法很少。问题是调用这些方法可能很耗时——它们可能会挂起我的应用程序(调用这些方法时不会释放 GIL)。所以我的问题是:

为这些方法调用释放 GIL 的最简单方法是什么?

(我知道如果我使用 C 库,我可以用一些额外的 C 代码来包装它,但这里我使用 C++ 和类)

【问题讨论】:

【参考方案1】:

不知道 SWIG 是什么,我还是会尝试回答 :)

使用类似的东西来释放/获取 GIL:

class GILReleaser 
    GILReleaser() : save(PyEval_SaveThread()) 

    ~GILReleaser() 
        PyEval_RestoreThread(save);
    

    PyThreadState* save;
;

在您选择的代码块中,利用 RAII 来发布/获取 GIL:


    GILReleaser releaser;
    // ... Do stuff ...

【讨论】:

谢谢,你节省了我一些时间。【参考方案2】:

真正的问题是 SWIG 没有很好地记录(我看到了使用更改日志进行搜索的提示;))。

好的,我发现我可以在 SWIG 中做内联函数并使用宏来释放/获取 GIL,它看起来像这样:

%inline %
    void wrappedFunction(OriginalObject *o, <parameters>) 
    Py_BEGIN_ALLOW_THREADS
    o->originalFunction(<parameters>);
    Py_END_ALLOW_THREADS

%

此函数在原​​始 C++ 中不存在,但在 python 模块中可用。这(几乎)正是我想要的。 (我想要的是像 python 装饰器那样包装原始方法)

【讨论】:

使用 Henrik 的。这是正确的,但是是不好的 c++ 实践。此外,我在发布 GIL 后从 dict 中提取数据时发生崩溃,因此我通常在 GIL 发布和重新获取之间不使用 python.h 中的任何函数。【参考方案3】:

您可以使用与 C 相同的 API 调用。没有区别。包含“python.h”并调用相应的函数。

另外,看看 SWIG 是否没有类型映射或其他东西来指示 GIL 不应该为特定功能保留。

【讨论】:

以上是关于在 C++ 代码中发布 Python GIL的主要内容,如果未能解决你的问题,请参考以下文章

如何在 boost::python 扩展模块中正确组合 C++ 和 Python 代码?

C++ 中的 Python 代码

从 c++ 代码运行 python 脚本并在 c++ 中使用 pythons 输出

在 Python 2.7 中编织内联 C++ 代码

在 python 中嵌入 c++ 代码会使你的 python 应用程序更快吗? [关闭]

如何在未安装 python 的系统上嵌入 python 代码来执行 C++ 代码