在我的PyQt5
程序中,我想启动一个运行某些代码的新线程:
class SlamThread(QThread):
"""docstring for SlamThread"""
def __init__(self, parent):
QThread.__init__(self, parent)
def setSlam(self, params):
self.params = params
def run(self):
self.slam = Slam()
self.slam.setParams(self.params)
self.slam.start()
Slam
用C ++编写并由pybind11转换的地方。
在我的主程序中,该代码由一个qAction
按钮触发:
def startSlam(self, ...):
params = ...
self.thread = SlamThread(self)
self.thread.setSlam(params)
self.thread.start()
for i in range(10):
print('done')
奇怪的是,它确实启动了一个新线程,在我的done
前,打印了Slam
。但是,当Slam
启动时,整个程序将挂起,直到Slam
完成。
在我的C ++ Slam
代码中,就像这样
int Slam::start()
{
init();
...
startSlam();
return 0;
}
startSlam
的运行时间只有几分钟。
答案 0 :(得分:1)
根据docs,在线程中执行对象时,必须调用gil_scoped_release和gil_scoped_acquire:
int Slam::start(){
pybind11::gil_scoped_release release;
init();
// ...
pybind11::gil_scoped_acquire acquire;
return 0;
}
或在绑定中:
pybind11::class_<Slam>(mymodule, "Slam")
.def(pybind11::init<>())
.def("setParams", &Slam::setParams)
.def("start", &Slam::start, pybind11::call_guard<pybind11::gil_scoped_release>());
您可以找到完整的测试here