我有一个用 C++ 编写的库,我使用 SWIG 包装并在 python 中使用。通常只有一个类,方法很少。问题是调用这些方法可能很耗时——它们可能会挂起我的应用程序(调用这些方法时不会释放 GIL)。所以我的问题是:
为这些方法调用释放 GIL 的最简单方法是什么?
(我知道如果我使用 C 库,我可以用一些额外的 C 代码来包装它,但这里我使用 C++ 和类)
真正的问题是 SWIG 没有很好地记录(我看到了使用更改日志进行搜索的提示;))。
好的,我发现我可以在 SWIG 中执行内联函数并使用宏来释放/获取 GIL,它看起来像这样:
%inline %{
void wrappedFunction(OriginalObject *o, <parameters>) {
Py_BEGIN_ALLOW_THREADS
o->originalFunction(<parameters>);
Py_END_ALLOW_THREADS
}
%}
此函数在原始 C++ 中不存在,但在 python 模块中可用。这(几乎)正是我想要的。(我想要的是像 python 装饰器那样包装原始方法)
不知道 SWIG 是什么,无论如何我都会尝试回答:)
使用类似这样的东西来释放/获取 GIL:
class GILReleaser {
GILReleaser() : save(PyEval_SaveThread()) {}
~GILReleaser() {
PyEval_RestoreThread(save);
}
PyThreadState* save;
};
在您选择的代码块中,利用 RAII 发布/获取 GIL:
{
GILReleaser releaser;
// ... Do stuff ...
}
您可以使用与 C 相同的 API 调用。没有区别。包括“python.h”并调用相应的函数。
另外,查看 SWIG 是否没有类型映射或其他东西来指示 GIL 不应该为特定功能保留。