我试图在boost :: python的帮助下将一些c ++功能包装到python中。我在使特定的回调机制工作时遇到了一些麻烦。以下代码段解释了我要做的事情:
//c++ side
class LoopClass {
public:
//some class attributes
void call_once(std::function const& fun) const;
};
void callOnce(LoopClass& loop, boost::python::object const& function) {
auto fun = [&]() {
function();
};
loop->call_once(fun);
}
boost::python::class_<LoopClass>("LoopClass")
.def("call_once", &callOnce);
//python side
def foo():
print "foo"
loop = LoopClass()
loop.call_once(foo)
以下是交易:函数call_once()
占用std::function
并将其放入队列中。 LoopClass维护一个永久循环,它在一个单独的线程中运行,并在某一点处理存储的回调函数的队列。要使boost::python::object
作为函数,必须显式调用强制转换运算符。这就是为什么我没有直接包装call_once()
,而是写了一个小转换函数callOnce()
,它通过lambda转发转换操作符调用。
无论如何,当我尝试运行此代码时,访问boost::python::object
失败并出现分段错误。我想在线程之间共享python对象并不容易。但是怎么做呢?
提前感谢您的帮助!
更新
我试图遵循@JanneKarila的建议
见Non-Python created threads。 - Janne Karila
我想这是找到解决方案的正确点,但不幸的是我无法弄清楚如何应用它。
我试过
void callOnce(LoopClass& loop, boost::python::object const& function) {
auto fun = [&]() {
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
function();
PyGILState_Release(gstate);
};
loop->call_once(fun);
}
哪个不起作用。我错过了什么或者太愚蠢了吗?
答案 0 :(得分:0)
你有没有打过PyEval_InitThreads(); ?
如果是这样的话,这个http://www.codevate.com/blog/7-concurrency-with-embedded-python-in-a-multi-threaded-c-application片段可以提供帮助吗?