[Interest] QTimer system goes down?

Thiago Macieira thiago.macieira at intel.com
Wed Oct 3 15:55:05 CEST 2012


On quarta-feira, 3 de outubro de 2012 10.44.56, Hugo Drumond Jacob wrote:
> Hi folks!
> 
> A couple of days ago I had some problems with a scenario like that shown
> below:
> 
> class SomeClassWorker : public QObject {
>     Q_OBJECT
> 
>     public:
>         SomeClassWorker(QObject* parent = 0) : QObject(parent) {

someTimer is initialised by the QTimer default constructor, which means it has 
no parent.

>             connect(&someTimer, SIGNAL(timeout()), this,
> SLOT(timeoutSlot()));
>     someTimer.start(100); //Do something every 100msecs.
>         }


>             worker = new SomeClassWorker(this);
> 
>             if(worker) {
>                 worker->moveToThread(&workerThread);

This does not move the timer to the other thread. Therefore, it is running on 
the current thread and the connection will be QueuedConnection.

> The SomeClass instance is running in main thread and the SomeClassWorker is
> running in a different thread.

Not all of it.

> Note that, on SomeClassWorker's constructor,
> the "someTimer" is connected to a private slot "timeoutSlot()" with
> Qt::AutoConnection connection type. On SomeClass's constructor, the
> SomeClassWorker is moved to her thread. Note yet that someTimer is a
> private member of SomeClassWorker and your parent is NULL (the default
> QTimer's constructor is called).

That's what I said :-)

> >From Qt 4.8.0 documentation, the Qt::AutoConnection's description is:
> "(default) If the signal is emitted from a different thread than the
> receiving object, the signal is queued, behaving as Qt::QueuedConnection.
> Otherwise, the slot is invoked directly, behaving as Qt::DirectConnection.
> The type of connection is determined when the signal is emitted."
> 
> So, when SomeClassWorker is moved to her thread, the someTimer still in
> main thread and for every "timeout()" signal emitted, the "timeoutSlot()"
> is queued called.

Yup, your understanding is correct.

> The problem: for some reason, the Qt timer system goes down (is correct say
> this, in this way?). The main thread still running, but, all
> "QTimer::timeout()" events aren't delivered.

I'm pretty sure that you've gone wrong with your analysis here. Since the 
timer is running in the main thread, the signals are delivered by way of the 
queued connection. That means two threads are running and communicating. We've 
just doubled the number of potential problems:

 - is the originating thread blocked, waiting for something?
 - is the thread you started blocked?

> To "solve" that, I set the someTimer parent to "this", in SomeClassWorker's
> constructor:
> PS: Note the quotation marks at solve.
> 
>     SomeClassWorker(QObject* parent = 0) : QObject(parent), someTimer(this)
> {
> 
> So, anyone can tell me what is wrong or what is happening?

We don't know what's wrong because the problem is in parts of the code that 
you did not paste. That is, it's in the "everything else" part of your 
application.

However, moving the timer to the auxiliary thread makes most sense. That 
thread will handle its own events, avoiding a context switch for the simple 
timeout.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 190 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20121003/9fa73477/attachment.sig>


More information about the Interest mailing list