[Interest] Poor QMethod::invoke performance across threads on i.MX53
Thiago Macieira
thiago.macieira at intel.com
Wed May 27 22:41:54 CEST 2015
On Wednesday 27 May 2015 15:02:36 Matthew Woehlke wrote:
> On 2015-05-18 03:46, Thiago Macieira wrote:
> > On Thursday 14 May 2015 18:18:52 Robert Daniels wrote:
> >> moveToThread(this);
> >
> > This is wrong. Never do "moveToThread(this)", since it's very difficult to
> > then destroy the QThread object. This is unrelated to the problem and
> > it's probably only for simplicity of your testcase.
>
> Sort of OT, but... why? If the object in question is destroyed by the
> same thread that created it, after the thread that the object
> "represents" has terminated cleanly, what is the problem?
The problem is a QThread living inside the thread that it started.
You can't destroy that object inside that thread because the QThread
destructor will wait() until the thread exits. And the thread can't exit until
the destructor has returned. That's a deadlock.
The correct way to dispose of the thread that did moveToThread(this); is:
void MyThread::run()
{
exec(); // or do whatever work you want to do
connect(this, &QThread::finished, this, &QObject::deleteLater);
moveToThread(QCoreApplication::instance()->thread());
}
This assumes that the main thread isn't blocked and is still processing
events. In fact, it assumes that QCoreApplication::instance() isn't being
destroyed, otherwise you have a race condition.
You can't do moveToThread(nullptr) because you need queued delivery in order
to call deleteLater() *after* finished() has finished emitting.
Another way, without subclassing:
class ThreadManager
{
Q_OBJECT
QThread thr;
public:
void doit()
{
connect(&thr, &QThread::finished,
[this]() {
thr->moveToThread(this->thread());
this->deleteLater();
})
thr.moveToThread(&thr);
thr.start();
}
};
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
More information about the Interest
mailing list