Reputation: 43
In my PyQt5
program, I want to start a new thread running some code:
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()
Where the Slam
is written in C++ and converted by pybind11.
And in my main program, the code is triggered by a qAction
button:
def startSlam(self, ...):
params = ...
self.thread = SlamThread(self)
self.thread.setSlam(params)
self.thread.start()
for i in range(10):
print('done')
Strange thing is that it did indeed started a new thread, done
is printed before my Slam
progrom. However, when Slam
started, the whole program hangs until Slam
finished.
In my C++ Slam
code, it is like this
int Slam::start()
{
init();
...
startSlam();
return 0;
}
where startSlam
takes few mins to run.
Upvotes: 1
Views: 377
Reputation: 244291
According to the docs when the object is executed in a thread you must call gil_scoped_release and gil_scoped_acquire:
int Slam::start(){
pybind11::gil_scoped_release release;
init();
// ...
pybind11::gil_scoped_acquire acquire;
return 0;
}
Or in the binding:
pybind11::class_<Slam>(mymodule, "Slam")
.def(pybind11::init<>())
.def("setParams", &Slam::setParams)
.def("start", &Slam::start, pybind11::call_guard<pybind11::gil_scoped_release>());
You can find the complete test here
Upvotes: 1