MFC full contact (III)
The post that the boss gave me yesterday: Oh, my first SDK-based window wrote a reply: "Why do you need peekmessage? This will make your program occupy all the CPU time that can be occupied. It is inferior to getmessage. When there is no message, the thread will be suspend ." This reply has made me think for a long time, and I have gained more. I really like this feeling. I wrote some simple and immature ideas, and the experts did not give me any further information. It is the spirit of sharing knowledge that makes me have a great harvest every day, thank you very much! A little out of question ~~
To be honest, when I ran my own example, I found that the CPU time was exhausted and the system was running very slowly. At that time, I really didn't reflect what was going on, in addition, I did not think much about the issues that I was concerned about at the time, I just wanted to see if the MFC-based program running would also take so much CPU time (although I knew at the time that the answer was definitely not, haha ). Until I saw the above reply, my brain was excited, and some of my original fully split understandings were linked by this reply.
First, the document tells mePeekmessage is a function with asynchronous thread behavior,The function returns immediately no matter whether messages exist in the message queue. While getmessage is a function with thread synchronization behavior. If there is no message in the message queue, the function will wait until there is at least one message in the message queue,. No matter whether the thread is synchronous or asynchronous, when peekmessage is returned under any circumstances, you will know that the Message Processing code in this example has no message in the message queue., Will be continuously executed cyclicallyIt is quite an endless loop, and it is strange that the CPU is not exhausted.
Secondly, the reply from the "male" boss reminds me of the Message Processing Mechanism in MFC: Do I also use the peekmessage function to retrieve messages from the message queue? So how does she avoid endless loops? So I will go back to the run function in the cwinthread class to check whether:
For (;;)
{
// Phase1: Check to see if we can do Idle Work
While (bidle &&! : Peekmessage (& m_msgcur, null, pm_noremove ))
{
// Call onidle while in bidle state
If (! Onidle (lidlecount ++ ))
Bidle = false; // assume "no idle" state
}
// Phase2: pump messages while available
Do
{
// Pump message, but quit on wm_quit
If (! Pumpmessage ())
Return exitinstance ();
// RESET "no idle" state after pumping "normal" Message
If (isidlemessage (& m_msgcur ))
{
Bidle = true;
Lelecount = 0;
}
} While (: peekmessage (& m_msgcur, null, pm_noremove ));
}
The initial bidle value in the Code is true,If the peekmessage return value is false, that is, when there is no message in the queueIf the entire Condition Statement in is true, the onidle function is called.Because lidlecountonidle is used as the input parameter of the onidle function and the initial value is 0, and the returned statement is return lcount <0, that is, the onidle return value must be false, bidle is assigned false, naturally, it jumps out of the loop. Next, go to the next loop and use the pumpmessage method to get the message. The essence of the pumpmessage is to call the getmessage method to obtain the message. In short, in two cycles, the peekmessage function is like a pathstone. check whether there is a message in the queue. If yes, what is the message, but she didn't remove the message from the queue. We can see it through the last parameter in the peekmessage method. At the same time, the two cycles are also alternating, like the second loop. When there is no message in the message queue, it will return to a loop again. The Design of MFC is to use the onidle method to address the idle state of the thread to which the form belongs. It also ensures that the thread does not enter sleep state due to getmessage.