7

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

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

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

4

3 回答 3

9

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

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

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

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

于 2009-10-16T14:21:01.860 回答
9

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

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

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

    ~GILReleaser() {
        PyEval_RestoreThread(save);
    }

    PyThreadState* save;
};

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

{
    GILReleaser releaser;
    // ... Do stuff ...
}
于 2009-10-16T09:12:03.067 回答
0

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

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

于 2009-10-16T09:01:03.433 回答