我正在尝试使用SWIG导向器从C ++调用Python代码。但是,如果代码在另一个线程中运行,我必须获取GIL。我的代码看起来大致相似(减去线程):
struct Callback {
virtual ~Callback() {}
virtual void call() {} // will be overwritten in Python
};
struct Foo {
Callback *c;
Foo(Callback* c) : c(c) {}
void doSomething() { c->call(); } // being called from another thread
};
的Python:
from demo import *
class MyCallback(Callback):
def call(*args):
print("python callback")
c = MyCallback()
f = Foo(c)
f.doSomething()
痛饮:
%module(directors="1", threads="1") demo
%feature("director");
%{
#include <test.h>
%}
%thread;
%include <test.h>
如何在调用Python回调之前获取GIL?
详细说明,SWIG的threads
功能创建了在调用C ++代码时释放GIL的代码,但是当从C ++调用Python代码时,它不会被重新获取,所以这就是我想要做的。 / p>
调用堆栈如下所示:Python - &gt; Foo.doSomething
- &gt; C ++ - &gt; Callback.call
- &gt;蟒。
答案 0 :(得分:2)
在Python手册的线程状态和全局解释器锁部分的Non-Python created threads小节中清楚地解释了获取GUIL。但是你说问题是如何从SWIG生成的代码中做到这一点。怎么样,添加到您的SWIG .i文件中:
struct PythonCallback: public Callback
{
virtual void call() {
getGIL();
lockedCall();
releaseGIL();
}
virtual void lockedCall() {} // will be overwritten in Python
};
您只需要公开PythonCallback
(而不是回调)及其lockedCall
方法,如果您希望通过SWIG&{39} call
将其重命名为%rename
指示。然后在Python中,您将从PythonCallback
派生,并覆盖call
方法(如果您lockedCall
,则实际上是%rename
方法)。