在 C++ 中释放 Python GIL代码

发布于 2024-08-08 03:55:36 字数 213 浏览 8 评论 0原文

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

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

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

I've got a library written in C++ which I wrap using SWIG and use in python. Generally there is one class with few methods. The problem is that calling these methods may be time consuming - they may hang my application (GIL is not released when calling these methods). So my question is:

What is the simplest way to release GIL for these method calls?

(I understand that if I used a C library I could wrap this with some additional C code, but here I use C++ and classes)

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

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

发布评论

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

评论(3

夜无邪 2024-08-15 03:55:36

不知道 SWIG 是什么,无论如何我都会尝试回答:)

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

class GILReleaser {
    GILReleaser() : save(PyEval_SaveThread()) {}

    ~GILReleaser() {
        PyEval_RestoreThread(save);
    }

    PyThreadState* save;
};

并在您选择的代码块中,利用 RAII 来释放/获取 GIL:

{
    GILReleaser releaser;
    // ... Do stuff ...
}

Not having any idea what SWIG is I'll attempt an answer anyway :)

Use something like this to release/acquire the GIL:

class GILReleaser {
    GILReleaser() : save(PyEval_SaveThread()) {}

    ~GILReleaser() {
        PyEval_RestoreThread(save);
    }

    PyThreadState* save;
};

And in the code-block of your choosing, utilize RAII to release/acquire GIL:

{
    GILReleaser releaser;
    // ... Do stuff ...
}
三寸金莲 2024-08-15 03:55:36

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

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

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

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

The real problem is that SWIG is not documented well (I saw hints to use changelog for searching ;) ).

Ok, I found out that I can do inline functions in SWIG and use macros to release/acquire GIL, it looks like this:

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

This function is not present in original C++, but available in python module. This is (almost) exactly what I wanted. (what I would like is to wrap original method like python decorator does)

臻嫒无言 2024-08-15 03:55:36

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

另外,请查看 SWIG 是否没有类型映射或其他内容来指示 GIL 不应为特定函数保留。

You can use the same API call as for C. No difference. Include "python.h" and call the appoproate function.

Also, see if SWIG doesn't have a typemap or something to indicate that the GIL shuold not be held for a specific function.

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