Logging safely from a worker thread?
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?
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.
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.
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.
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
精彩评论