[Qt-interest] QThread event loop running in main thread?
BRM
bm_witness at yahoo.com
Tue Dec 28 15:54:54 CET 2010
Well, perhaps some I can shed a little light per why I changed over...
1. Under Qt 4 (at least since 4.4 when I started using it), QThread by default
runs the exec() - so you automatically have the event loop by simply doing:
QThread myThread;
myThread.start();
So no allocation necessary there - it can just as easily be on the stack.
2. I use to do something similar which two tightly bound classes - myThread and
myThreadInstance. myThread was derived from QThread and allocated a
myThreadInstance object inside of the run() then connected its signals to the
signals/slots of myThreadInstance before calling exec(). This made it look like
one object to the outside and guaranteed the work was done in the new thread.
However it was a lot of work to maintain - since I now had three places to
update whenever I needed to change a slot or add a slot, etc. - myThreadInstance
(for generating a signal or receiving a slot), myThread (for connecting the
outside world to myThreadInstance), and whatever was using myThread.
However, using the "proper" way - I really only need to create myThreadInstance
and let the outside world work on it directly. The only difference is that I
have to also create a thread and move it to that thread. Nothing else changes.
In converting over to the new paradigm, I also did something that was half-way
in-between - I created a class myThread that was not derived from QThread but
instead QObject. The class did the same thing, but it kept a QThread class on
the stack and did the whole moveToThread for me. It made for a nice transition
as I learned the new approach since I could quickly and easily convert back to
the old approach if it didn't work out.
Now, I'm not saying that this "proper" way is The Right Way for all instance -
it's not. You've certainly shown a use case where having a wrapper class is
certainly part of the design to manage the work of the worker thread, and that's
perfectly fine. But you don't have to do so by deriving that handler class from
QThread, so you could make it a little simpler if you liked:
class myThreadWorker : QObject {
...
};
class myThreadHandler : QObject {
Q_OBJECT
public:
...
public Q_SLOTS:
// public interface
Q_SIGNALS:
// signals going out
void workerTerminate();
...
protected Q_SLOTS:
// signals received from the worker
...
private:
QThread workerThread;
myThreadWorker worker;
};
myThreadHandler::myThreadHandler(QObject* _parent) : QObject(_parent) {
worker.moveToThread(&workerThreader);
// connect signals & slots
connect(this,SIGNAL(workerTerminate()),&workerThread,SLOT(quit()));
workerThread.start();
}
myThreadHandler::~myThreadHandler() {
Q_EMIT workerTerminate();
workerThread.wait();
}
You still get the same benefits you listed, but a little nicer paradigm - just
as tightly coupled if you like but easy to move around at the same time.
I do agree that it is hard to justify refactoring older code for the new
paradigm - I'll get to it eventually, but it's certainly not a priority since it
is working.
$0.02
Ben
----- Original Message ----
> From: Mihail Naydenov <mlists at ymail.com>
> To: Thiago Macieira <thiago at kde.org>; qt-interest at qt.nokia.com
> Sent: Tue, December 28, 2010 5:52:50 AM
> Subject: Re: [Qt-interest] QThread event loop running in main thread?
>
> With the risk of being ashamed I must admit I do use the wrong way :)
>
> I still am not sold why should I not be doing it. I find the reasons against
>it
>
> to academic - "Do the work in a object, devoted to that, and let a specific
> class handle the threading part - encapsulation and specialization".
> Well, merging the two is however to damn convenient in practice.
>
> The scenario I use (inspired by QFileSystemWatcher ) is to have Worker and
> WorkerEngine.
>
> Worker is simple interface to the world (signals, slots, functions), manages a
>
> private WorkerEngine.
> WorkerEngine is qthread and is lives on that thread.
>
> Worker queues work for WorkerEngine be invoking its methods, also handles
> cancellation by calling its cancel/quit functions.
>
> WorkerEngine does all the work in Q_INVOCABLE functions, also sends results by
>
> invoking methods (in most cases the actual public result-signals), on the
> Worker.
>
> Yes the design is "bad" because of the tight coupling of two, even three
> classes, but to the world it is one - Worker, all other mess is impl. detail.
> The important part however is - it can not be made simpler than that to have
> threaded work done.
>
> Both reimpl run() and having separate qthread object to carry WorkerEngine
> introduces some (uneeded) addition management.
> In first case - to have a manual work queue;
> In the second - to have stubs for communicating with qthread, you lose
>sleep(),
>
> have (yet) another QObject allocation and management. Yes these are all
>trival,
>
> but as I said - unnecessary, you gain nothing (at least I don't).
>
>
> So in the end the scenario is by no means perfect, but cant be more simpler.
>
> Thanks
> MihailNaydenov
>
>
> ----- Original Message ----
> > From: Thiago Macieira <thiago at kde.org>
> > To: qt-interest at qt.nokia.com
> > Sent: Tue, December 28, 2010 12:28:59 AM
> > Subject: Re: [Qt-interest] QThread event loop running in main thread?
> >
> > On Monday, 27 de December de 2010 18:00:44 Hannu Shemeikka wrote:
> > > Maybe you guys, Nokia or whoever is responsible, should update the
> > > documents. Especially the QThread-stuff. It's written there that "to
> > > create your own threads, subclass QThread and reimplement run()."
> >
> > Why?
> >
> > That is not wrong. It is accurate, even if not complete.
> >
> > Like Mihail said further down the thread, the wrong thing to do is to have
> > slots in the class derived from QThread and/or using moveToThread(this).
> >
> > If you treat the QThread object like I said, as the object managing an
> > operating system resource (the thread), not the work to be done, you're
>fine.
> >
> > --
> > Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> > Senior Product Manager - Nokia, Qt Development Frameworks
> > PGP/GPG: 0x6EF45358; fingerprint:
> > E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
> >
>
>
>
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at qt.nokia.com
> http://lists.qt.nokia.com/mailman/listinfo/qt-interest
>
More information about the Qt-interest-old
mailing list