PDA

View Full Version : Handler thread to process messages asynchronously



Luc4
6th April 2011, 23:49
Hi! I'm in the need of writing a thread that continuously processes messages, one after the other (and maybe with a priority), coming from other threads.
I used something similar in an Android application using the Handler class (http://developer.android.com/reference/android/os/Handler.html). Is there anything similar in Qt or should I implement it myself using queues, Semaphores etc...?
What I found so far is the QAbstractMessageHandler, but it doesn't seem to be what I'm looking for.
Is there anything else that may be of help to implement such a thing?
Thanks for any advice!

high_flyer
8th April 2011, 09:57
Have a look at QEventLoop.

Luc4
23rd April 2011, 12:01
May you give me a little more information about how to use the QEventLoop class in this context?

I read some other threads around and found this way: I create a handler object that responds to requests using slots. I instantiate this object in a new thread and I send requests from other threads by using QMetaObject::invokeMethod passing Qt::QueuedConnection or using signals and slots.

Do you consider this approach good?
Thank you for the information!

squidge
23rd April 2011, 12:24
You can use signals and slots or you can have a look at QApplication::postEvent. Since you'll only have one consumer in this context, the later seems more logical - you would send the events directly to your handler thread rather than the handler thread having to connect to your signals.

Luc4
24th April 2011, 13:08
This is somehow what you were talking about? Or am I completely off the way?


#include <QtCore/QCoreApplication>
#include <QEventLoop>
#include <QWaitCondition>
#include <QMutex>
#include <QThread>

class MyEventLoop : public QThread
{
public:
MyEventLoop() {}
bool event(QEvent* event)
{
qDebug("Processing event.");
return true;
}
void run() {exec();}
};

int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);
QThread thread;
thread.start();

for (int i = 0; i < 10; i++) {
QWaitCondition cond;
QMutex mutex;
cond.wait(&mutex, qrand() % 4000);

qDebug("Sending event.");
QCoreApplication::postEvent(&thread, new QEvent(QEvent::Hide));
}

return a.exec();
}

I would like to use this even following the command design pattern, so sending requests in the form of objects to better describe the request. Sill this is a good way to go? I suppose I have to subclass QEvent to add whatever else I need right?

Speaking about memory management, the documentation obviously tell me to allocate the object in the heap, but does it free memory automatically after the event(...) method has returned true or am I supposed to do it there myself?

The approach I reported in the other post was correct as well?

Thanks!

squidge
24th April 2011, 16:07
Yes, like that.

So your constructor would be like so:



myEvent::myEvent(int yourData) : QEvent(QEvent::User)
{
this->yourData = yourData; // etc...
}


and then:



bool myThread::event( QEvent * e )
{
if (e->type() >= QEvent::User)
{
myEvent *e = static_cast<myEvent*>(e);
(...)


As stated in the documentation, you must not access the object again once it has been posted:


The event must be allocated on the heap since the post event queue will take ownership of the event and delete it once it has been posted. It is not safe to access the event after it has been posted.