views:

164

answers:

4

In one of my worker threads I want to do some logging. The log messages are channeled to a GUI textarea, which should only be accessed from the main thread. So the problem is: how do I log messages safely from a worker thread?

My current solution is to have the logging function check whether we are currently in the main thread. If yes, then just log. If no, then add the message to a queue of pending messages (this queue is protected by a mutex). The main thread also has a timer who's callback function (which also executes in the main thread) takes care of dequeueing and logging any pending messages.

Above solution is just my own little invention. Are there better or more standard solutions to this problem?

+1  A: 

I recommend that you just generalise the general 'sending log messages from a thread' case and not special-case sending messages from the main/GUI thread.

It is normal (in my varied experience) to just always queue log messages for the main/gui loop to consume, even if posted in the main/gui thread.

It simplifies the code, and the display of log messages is rarely time-critical (and doesn't display before a repaint is serviced anyway etc).

It also preserves the (general) natural order of messages.

You typically send your gui thread a 'log message waiting' event to wake it up too.

Will
I'm not sure if I understand. You mean that you always add log messages to an event queue, regardless of which thread you're in?
StackedCrooked
Exactly. Make the 'sending log messages from another thread' the general case.
Will
+3  A: 

If you have one rule for logging in one thread ("just do it now") and another rule for other threads ("add it to a queue for later") then your logging will get out of order. I can't imagine this being a good thing. Have one rule for all your logging - add it to the queue.

Kylotan
+1  A: 

I would let the worker thread emit a message signal whenever it wants to log something. The GUI thread can then subscribe to the message signal from your thread, and perform the processing of the message in the main UI thread.

Qt will handle the problem of delivering signals over thread boundaries. See Signals and slots accross threads for more information. Have a look at the non-blocking fortune client-server example to see cross-thread boundary signals and slots in action.

Ton van den Heuvel
I'm not familiar with signals in QT, but can the actual message to be logged form part of the "signal"?
Roddy
Yes, that is possible. A signal in Qt is defined as a class method, and the parameters for that method are part of the signal. You can basically pass any type as a parameter for a Qt signal, including a custom defined class: http://qt.nokia.com/doc/main-snapshot/custom-types.html
Ton van den Heuvel
A: 

I would log each message to a logging class. The GUI thread will periodically call the logging class for messages. In the logging class you can easily add a locking mechanism for adding and removing messages

PoweRoy