[Interest] QEventLoop -- not sure I am correctly using this

Mandeep Sandhu mandeepsandhu.chd at gmail.com
Tue Dec 3 05:58:51 CET 2013


Hi Jason,


As Andre pointed out, have an 'outer' class manage the worker object
and thread for you instead of doing it from within your worker.

Eg:

SomeManagerClass::SomeManagerClass(QObject *parent) : QObject(parent)
{
    worker = new MyWorker(); // parentless
    workerThread = new QThread(); // parentless

    // Move worker object to new thread
    worker->moveToThread(workerThread);

    connect(worker, SIGNAL(workFinished()), this, SLOT(onWorkFinished()));

    workerThread->start();
}
...
...
SomeManagerClass::~SomeManagerClass()
{
    workerThread->quit();
    workerThread->wait();
}

As for you event loop, I don't see any obvious issues.

I guess the reason you decided to wait for 1 second using an ev loop,
rather than have a slot handle the timeout was to make the code look
simple (synchronous)?

What platform are you running this on?

-mandeep


On Tue, Dec 3, 2013 at 1:59 AM,  <andre at familiesomers.nl> wrote:
> Hi,
>
> It looks to me, that you're indeed doing it wrong. It seems you're
> trying to let your backgroundtaskmanager both manage a thread and be
> _in_ that thread. That is not the way to go. I'd separate the two
> issues. If you want the backgroundTaskManager to run in it's own thread,
> then either just make it a "front" for a backend implementation that you
> move to a thread managed by backgroundTaskManager, or just let let the
> whole backgroundTaskManager be unconcerned with what thread it runs in,
> and have whoever creates/owns/manages it be responsible for moving it to
> a separate thread if that is desirable.
>
> Then about your use of QEventLoop: no, I'd not use it this way.
> QEventLoop is not meant as an escape to 'pause' execution of your
> method. If you want to wait for about a minute, why not use a QTimer
> directly? I don't see a need for QEventLoop here at all.
>
> As to why your setup doesn't work and your eventloop seems blocked
> during your background task: I guess you gave your BackgroundTaskManager
> a parent object? That won't work. A whole parent/child tree must live in
> the same thread. So, I guess your BackgroundTaskManager did not actually
> get moved to the thread at all.
>
> André
>
>
> Jason Kretzer schreef op 02.12.2013 20:27:
>> Maybe that last bit would be a bit more clear.
>>
>> The first qDebug statement writes out — I have it set to give the
>> time when it is written as well — but the qDebug does not write
>> until after the heavy task is completed in backgroundtaskmanager. Any
>> other time, this performs as expected, ticking along every second.
>>
>> -Jason
>>
>> _- - - - - - - - - - - - - - - - - - - - - - -_
>> _JASON R. __KRETZER_
>> _ _
>> _APPLICATION DEVELOPER_
>> _Google # 606-887-9011_
>> _Cell # 606-792-0079_
>> _Jason at gocodigo.com_
>> _ _
>> _“QUIDQUID LATINE DICTUM SIT ALTUM VIDETUR”_
>> _ _
>>
>> On Dec 2, 2013, at 2:14 PM, Jason Kretzer <Jason at gocodigo.com> wrote:
>>
>>> Good Day,
>>>
>>> I have in my application, two classes. When the application starts
>>> up, one of the classes -backgroundtaskmanager - gets instantiated.
>>> In the constructor, a QTimer is started to timeout every 5 minutes
>>> and call runTasks. The instantiation is then moved to a separate
>>> thread so that it can run without impacting the rest of the
>>> application.
>>>
>>> Here are the contents of the constructor.
>>>
>>> QTimer* timer = new QTimer(this);
>>> connect(timer, SIGNAL(timeout()), this, SLOT(runTasks()));
>>> timer->start(300000); //fiveminutes
>>> thread = new QThread();
>>> this->moveToThread(thread);
>>> thread->start();
>>>
>>> The second class -player- is instantiated in the main thread. Once
>>> it is instantiated, it begins doing other tasks. Basically, a method
>>> is called with the following code. This code is designed to make the
>>> while loop delay for one second before executing the rest of the
>>> loop (one second-ish, I know it is not perfect but it has good
>>> enough resolution for what I need).
>>>
>>> while(!taskQueue.isEmpty()) {
>>> qDebug() << “BEFORE QEVENTLOOP”;
>>> QEventLoop wait1Sec;
>>> QTimer::singleShot(1000, &wait1Sec,SLOT(quit()));
>>> wait1Sec.exec();
>>> aDebug() << “AFTER QEVENTLOOP”;
>>>
>>> QList<Task*> instances;
>>> for(int t=seconds; t>previousTime; t—) {
>>> QList<Task*> vals = taskQueue.values(t);
>>> while(!vals.isEmpty()) {
>>> instances.insert(0, vals.takeLast());
>>> }
>>> taskQueue.remove(t);
>>> }
>>> previousTime = seconds;
>>> miliSeconds = QDateTime::currentMSecsSinceEpoch() -
>>> today.toMSecsSinceEpoch();
>>> seconds = miliSeconds/1000;
>>> }
>>>
>>> NOTE: the two sets of tasks these do are not related.
>>>
>>> So, anyway, every 5 minutes the tasks in backgroundtaskmanager are
>>> run. Some of these tasks can take up to a minute. When the
>>> backgroundtaskmanager class runs a task that does take this long
>>> (remember it is in a separate thread), the player class code above
>>> gets hung in what appears to be the inside of the QEventLoop. The
>>> qDebug statements don’t write out until the tasks in the
>>> backgroundtaskmanager are finished. Then it rushes through to catch
>>> up.
>>>
>>> My question is, am I correctly doing this at all? Is this the proper
>>> use of a QEventLoop?
>>>
>>> Thanks!
>>>
>>> -Jason
>>>
>>> _- - - - - - - - - - - - - - - - - - - - - - -_
>>> _JASON R. __KRETZER_
>>> _ _
>>> _APPLICATION DEVELOPER_
>>> _Google # 606-887-9011_
>>> _Cell # 606-792-0079_
>>> _Jason at gocodigo.com_
>>> _ _
>>> _“QUIDQUID LATINE DICTUM SIT ALTUM VIDETUR”_
>>> _ _
>>> <image001.png>
>>> _______________________________________________
>>> Interest mailing list
>>> Interest at qt-project.org
>>> http://lists.qt-project.org/mailman/listinfo/interest
>>
>>
>> _______________________________________________
>> Interest mailing list
>> Interest at qt-project.org
>> http://lists.qt-project.org/mailman/listinfo/interest
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest



More information about the Interest mailing list