There has been a general discussion about the efficiency of the Qt event loop, and whether or not the application or thread event loops block or spin burning CPU cycles. I desire to write an application that is patterned more after an RTOS type of construct wherein secondary threads pend until they actually have data to process or exit. Intuitively, it would seem that any Qt application or thread that implements event handling, must have the event loop running. This subject has been discussed on these forums, that is the necessity to have an event loop running for a thread to receive and process emitted signals.
In my current design, I anticipate using a Qt console based application (running exec()) running the Qt state machine framework (running exec()) with several secondary threads which will NOT run event loops. Per previous dialog, the general rule was a thread can emit signals without an event loop, but the receiver must be running an event loop to propertly detect the event.
When I think of characterizing the efficiency of a thread, it really comes down to a duty cycle calculation, that is, how often is the thread running burning CPU cycles relative to the time it spends blocking. Certainly this duty cycle will change as a function of activity, but I want to characterize the behavior for a more nominal condition where the application/thread running exec() is not being actively tickled by signals or events.
To that end, I am trying to come up with a methodology to characterize the efficiency of the QCoreApplication::exec() call as well as the QThread::exec() call. By inspection of the Qt source code, exec() will eventually call QEventLoop:rocessEvents, and
the QAbstractEventDispatcher calls a Windows or Linux specific implementation.
QtCored4.
dll!QEventDispatcherWin32
::processEvents(QFlags<enum
QEventLoop::ProcessEventsFlag> flags
={...
}) Line
834 C
++QtGuid4.
dll!QGuiEventDispatcherWin32
::processEvents(QFlags<enum
QEventLoop::ProcessEventsFlag> flags
={...
}) Line
1170 + 0x15 bytes C
++QtCored4.
dll!QEventLoop::processEvents(QFlags<enum
QEventLoop::ProcessEventsFlag> flags
={...
}) Line
150 C
++QtCored4.
dll!QEventLoop::exec(QFlags<enum
QEventLoop::ProcessEventsFlag> flags
={...
}) Line
201 + 0x2d bytes C
+
QtCored4.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags={...}) Line 834 C++
QtGuid4.dll!QGuiEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags={...}) Line 1170 + 0x15 bytes C++
QtCored4.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags={...}) Line 150 C++
QtCored4.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags={...}) Line 201 + 0x2d bytes C+
To copy to clipboard, switch view to plain text mode
Under Windows, (file C:\Qt\4.7.3\src\corelib\kernel\qeventdispatcher_wi n.cpp), QEventDispatcherWin32:rocessEvents() is called. Within the method, there are conditions wherre MsgWaitForMultipleObjectsEx() is called blocking the thread. The aboutToBlock() signal is emited prior to the thread blocking, and conversely, the awake() signal is emitted when the thread unblocks.
Under Linux (file C:\Qt\4.7.3\src\corelib\kernel\qeventdispatcher_un ix.cpp), the doSelect() API is called to pend the thread, and the aboutToBlock() and awake() signals are emitted to frame the blocking session.
My original idea on characterizing the duty cycle was to implement handlers for these two signals and record the time at each point so a duty cycle calculation of thread "blocking" time could be determined relative to thread active time burning CPU cycles.
However, the eventloop for the main application is implemented within QCoreApplication::exec() as a local stack based variable QEventLoop. I am unable to override the implementation of QCoreApplication::exec() without access to the
private members of the base class.
Perhaps I am approaching this incorrectly, and there some profiling tool available to characterize the exec() event loop to get a metric on its efficiency (or lack thereof).
Anybody have any thoughts on this or have already characterized exec()'s behavior?
Bookmarks