I often wondered the same thing!
The main GUI loop looks like this: in pseudocode:
void App::exec() { for(;;) { vector<Waitable> waitables; waitables.push_back(m_networkSocket); waitables.push_back(m_xConnection); waitables.push_back(m_globalTimer); Waitable* whatHappened = System::waitOnAll(waitables); switch(whatHappened) { case &m_networkSocket: readAndDispatchNetworkEvent(); break; case &m_xConnection: readAndDispatchGuiEvent(); break; case &m_globalTimer: readAndDispatchTimerEvent(); break; } } }
What is Pending? Well, it depends on the system. On UNIX, it is called a โfile descriptor,โ and โwaitOnAllโ is called a :: select system call. The so-called vector<Waitable> is ::fd_set on UNIX, and whatHappened is actually requested through FD_ISSET . Actual handlers are obtained in different ways, for example, m_xConnection can be taken from :: XConnectionNumber (). X11 also provides a high-level portable API for this - :: XNextEvent () - but if you used this, you would not be able to wait for multiple event sources at the same time.
How does blocking work? "waitOnAll" is a system call that tells the OS that your process is moving to a "sleep list". This means that you are not given any processor time until the event occurs on one of those waiting. This means that your process is idle, consuming 0% CPU. When an event occurs, your process will briefly respond to it, and then return to the waiting state. GUI applications spend almost all of their time idling.
What happens to all processor cycles during sleep? It depends. Sometimes a different process will be useful to them. If not, your OS will be busy with the processor cycle or put it into temporary mode with low power consumption, etc.
Please request more information!
Iraimbilanja Mar 18 '09 at 14:29 2009-03-18 14:29
source share