在C++代码中释放Python GIL
我有一个用C++写的库,我通过SWIG把它包装起来,然后在Python中使用。通常这个库里有一个类和几个方法。问题是,调用这些方法可能会耗费很多时间——它们可能会让我的应用程序卡住(因为在调用这些方法时,GIL没有被释放)。所以我想问的是:
有没有什么简单的方法可以在调用这些方法时释放GIL?
(我明白如果我使用的是C库,我可以通过一些额外的C代码来包装它,但这里我使用的是C++和类。)
3 个回答
0
你可以用跟C语言一样的API调用,没什么不同。只需要包含“python.h”这个文件,然后调用合适的函数就行。
另外,看看SWIG有没有什么类型映射之类的东西,可以指示某个特定的函数不需要持有GIL(全局解释器锁)。
9
真正的问题是,SWIG的文档写得不太好(我看到有人建议用更新日志来查找信息;)
好吧,我发现我可以在SWIG中使用内联函数,并用宏来释放或获取全局解释器锁(GIL),它看起来是这样的:
%inline %{
void wrappedFunction(OriginalObject *o, <parameters>) {
Py_BEGIN_ALLOW_THREADS
o->originalFunction(<parameters>);
Py_END_ALLOW_THREADS
}
%}
这个函数在原来的C++代码中并不存在,但在Python模块中可以找到。这几乎正是我想要的。(我希望的其实是像Python装饰器那样包装原始方法)
9
虽然我对SWIG一点都不了解,但我还是试着回答一下 :)
可以使用类似下面的代码来释放或获取GIL:
class GILReleaser {
GILReleaser() : save(PyEval_SaveThread()) {}
~GILReleaser() {
PyEval_RestoreThread(save);
}
PyThreadState* save;
};
然后在你选择的代码块中,利用RAII来释放或获取GIL:
{
GILReleaser releaser;
// ... Do stuff ...
}