为什么运行pybind11 c ++ lib的pyqt5 QThead仍然挂起我的主GUI?

时间:2019-05-02 02:49:52

标签: python multithreading pyqt5 pybind11

在我的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的运行时间只有几分钟。

1 个答案:

答案 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

相关问题