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

Jason Kretzer Jason at gocodigo.com
Wed Dec 4 22:51:46 CET 2013


So, question about telling the manager class what to do.

>From my main thread, I instantiate the manager class which is implemented according to what you wrote below.  I want to be able to tell the manager when to start and stop worker inside that it is managing.

Would having a call to a public function of the manager work the way I want when called from the main thread?

—Main Thread———
Manager *manager = new Manager(); //with constructor and worker inside as described
…
…
…
//now some condition occurs, I want the worker on the inside to start doing its thing
manager->startWorker();
…
…
…
//now some other condition occurs, I want the worker on the inside to stop doing its thing
manager->stopWorker();


Alternatively, through the signal/slot mechanism.  Regardless, will the above pull it out of its thread?

Thanks,

-Jason

- - - - - - - - - - - - - - - - - - - - - - -
Jason R. Kretzer

Application Developer
Google # 606-887-9011
Cell # 606-792-0079
Jason at gocodigo.com<mailto:Jason at gocodigo.com>

“quidquid latine dictum sit altum videtur”


[cid:image001.png at 01CECA4D.CA4030A0]

On Dec 4, 2013, at 12:46 AM, Mandeep Sandhu <mandeepsandhu.chd at gmail.com<mailto:mandeepsandhu.chd at gmail.com>> wrote:


On Tue, Dec 3, 2013 at 10:39 PM, Jason Kretzer <Jason at gocodigo.com<mailto:Jason at gocodigo.com>> wrote:
Ah, I see!  Now I understand what you mean.

I rewrote my “player” object to use a Qtimer that fires every 1 second and is started/stopped according to signals.  However, it still has the same problem where the timer won’t fire sometimes for extended periods.  I guess that means something in the overall eventloop is blocking it.  So, I believe I will try to implement it in the worker kind of format you have below where I can put the timer in a thread.

Also, as Thiago already suggested, while you're debugging, print out the thread ID from the worker thread and main thread objects just so that you know that they're running in different threads.

-mandeep



I appreciate the help!

-Jason

- - - - - - - - - - - - - - - - - - - - - - -
Jason R. Kretzer

Application Developer
Google # 606-887-9011<tel:606-887-9011>
Cell # 606-792-0079<tel:606-792-0079>
Jason at gocodigo.com<mailto:Jason at gocodigo.com>

“quidquid latine dictum sit altum videtur”


<image001.png>

On Dec 2, 2013, at 11:58 PM, Mandeep Sandhu <mandeepsandhu.chd at gmail.com<mailto:mandeepsandhu.chd at gmail.com>> wrote:

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<mailto: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<tel:606-887-9011>_
_Cell # 606-792-0079<tel:606-792-0079>_
_Jason at gocodigo.com<mailto:Jason at gocodigo.com>_
_ _
_“QUIDQUID LATINE DICTUM SIT ALTUM VIDETUR”_
_ _

On Dec 2, 2013, at 2:14 PM, Jason Kretzer <Jason at gocodigo.com<mailto: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<tel:606-887-9011>_
_Cell # 606-792-0079<tel:606-792-0079>_
_Jason at gocodigo.com<mailto:Jason at gocodigo.com>_
_ _
_“QUIDQUID LATINE DICTUM SIT ALTUM VIDETUR”_
_ _
<image001.png>
_______________________________________________
Interest mailing list
Interest at qt-project.org<mailto:Interest at qt-project.org>
http://lists.qt-project.org/mailman/listinfo/interest


_______________________________________________
Interest mailing list
Interest at qt-project.org<mailto:Interest at qt-project.org>
http://lists.qt-project.org/mailman/listinfo/interest
_______________________________________________
Interest mailing list
Interest at qt-project.org<mailto:Interest at qt-project.org>
http://lists.qt-project.org/mailman/listinfo/interest
_______________________________________________
Interest mailing list
Interest at qt-project.org<mailto:Interest at qt-project.org>
http://lists.qt-project.org/mailman/listinfo/interest



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20131204/0a53ea62/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image001.png
Type: image/png
Size: 13452 bytes
Desc: image001.png
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20131204/0a53ea62/attachment.png>


More information about the Interest mailing list