星座/上下文:
一个C++可执行文件(1),它动态链接一个C++共享库emb.so(2)
依次运行嵌入式python解释器(3),该解释器将调用自定义python函数(4)。
使用pybind11嵌入了Python解释器(3)。
从C++调用Python函数可以简化为:
py::module::import("test").attr("my_func")();
可执行文件(1)有一个主循环,在其中可以执行其他一些工作,但是它将定期调用python函数。
观察:
问题:
为什么变体2这么慢,我该如何解决?
我的猜测是这与GIL有关,我尝试在返回到主循环之前释放包装emb.so中的GIL,但是我无法在没有段错误的情况下执行此操作。
有任何想法吗?
最佳答案
事实证明,这与以下问题密切相关:
Embedding python in multithreaded C application
(请参阅答案https://stackoverflow.com/a/21365656/12490068)
我通过在调用嵌入式Python代码后显式释放GIL来解决了这个问题:
state = PyGILState_Ensure();
// Call Python/C API functions...
PyGILState_Release(state);
如果要在函数或其他C++范围内执行此操作,并且要创建python对象,则必须确保释放GIL后不调用python对象的desctructor。
所以不要:
void my_func() {
gil_state = PyGILState_Ensure();
py::int_ ret = pymodule->attr("GiveMeAnInt")();
PyGILState_Release(gil_state);
return ret.cast<int>();
}
但是相反
void my_func() {
int ret_value;
gil_state = PyGILState_Ensure();
{
py::int_ ret = pymodule->attr("GiveMeAnInt")();
ret_value = ret.cast<int>();
}
PyGILState_Release(gil_state);
return ret_value;
}
关于python - 使用GIL和多线程处理嵌入式Python解释器调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61367199/