http://blog.csdn.net/libaineu2004/article/details/40398405
1. Threads are divided into UI threads and worker threads, UI threads have Windows, Windows build message queues, the UI thread maintains Message Queuing, and Message Queuing is the biggest difference between an interface thread and a worker thread. So the user interface is generally called the UI thread, there is no interface called the worker thread, the UI thread because of the interface, so the system will maintain a message queue for it, the worker thread there is no message queue.
2, the worker thread originally did not have the message queue, but you can force to add one, generally as long as your thread appears in the GDI's call will appear a message queue, the thread if the call GetMessage (), you can force a message loop, the system will be added to the thread a message queue, also use PeekMessage () to force the system to join a message queue. Message delivery for worker threads is sent through the PostThreadMessage function. That is, in a worker function, if a function is called on a message, the operating system automatically creates a message queue for the work line.
3. The so-called UI thread has a window, and the window has built its own message queue. The so-called worker thread initial state has no self-built message queue.
4. UI thread Message processing process
UI threads and worker threads are only available when using the MFC framework. The difference between a UI thread and a worker thread is that the operating system creates and maintains a message queue for the UI thread.
In fact, when the thread is created (either API or MFC), it is a worker thread. When a thread calls a function that sends a message or extracts a message or graphical user interface, the system creates a message queue and a threadinfo structure for it, and the line friend is called the UI thread.
VC development of the main thread of the console program is a worker thread, the main thread of other programs is the UI thread. _beginthreadex/createthread such as a line created by a function Cheng think of a worker thread, AfxBeginThread can create worker threads and UI threads based on parameters.
(1) from user input to System message queue
The operating system monitors the computer's input devices such as keyboards and mice, generates a message for each input event, and temporarily places the message in the system message queue. Where the window handle of the message is calculated by the system based on the mouse or the area where the cursor is located.
(2) from system Message Queuing to thread Message Queuing
The system has a dedicated thread that takes the message out of the system message queue and posts the message to the message queue corresponding to the UI thread that created it, based on the target object (window handle) of the message. Each UI thread has and has only one message queue.
(3) UI thread processing messages
The UI thread initiates a message loop that extracts a message from the message queue for this thread each time, and then forwards it to a specific form object based on the information it contains, and the form procedure function that corresponds to the form object is called to process the messages.
MSG msg; Represents a message
BOOL BRet;
To remove a message from the UI thread message queue
while ((BRet = GetMessage (&msg, NULL, 0, 0))! = 0)
{
if (BRet = =-1)
{
Error handling code, usually directly exiting the program
}
Else
{
TranslateMessage (&MSG); Convert message Format
DispatchMessage (&MSG); Distributing messages to the appropriate form
}
}
GetMessage () waits for a message to return, PeekMessage () returns a message or null immediately, GetMessage () is removed from the queue after the message is received (except WM_PAINT), PeekMessage () is based on the parameter pm_ Noremove or Pm_remove to decide whether or not to delete.
The TranslateMessage () function is primarily used to convert wm_keydown and WM_KEYUP messages WM_CHAR messages. So if you want to intercept wm_keydown and WM_KEYUP messages, you need to overload the PreTranslateMessage () function of the form class for analysis.
The DispatchMessage () function forwards this message to the form object that corresponds to this handle, based on the form handle contained in the extracted message. The function that responds to the message is called the form procedure (Window Procedure). If custom processing is required, the DefWindowProc () function of the form class is overloaded. A form procedure is a function, one for each form, in the form of the following:
LRESULT CALLBACK mainwndproc (...)
{
......
Switch (umsg)//classify by message identifier
{
Case WM_CREATE:
Initializes the form.
return 0;
Case WM_PAINT:
Draw a form
return 0;
//
Handling Other messages
//
Default
Go to call the system default message handler function
Return DefWindowProc (hwnd, umsg, WParam, LParam);
}
......
}
http://blog.csdn.net/hebezai/article/details/10383323
Also talk about my understanding of UI threads and worker threads
The UI thread, also called the interface thread, is capable of responding to specific messages of the operating system, including interface messages, mouse keyboard messages, custom messages, and so on, on the basis of a common worker thread, with a message loop, which constantly gets the messages distributed by the operating system or other threads. It is a thread that executes a For loop master), and then finds the corresponding message processing object/function based on this message, and if there is no message to be processed, let the thread wait, yielding the CPU time slice to show that the thread has been "online" until a particular exit message ends the thread.
Worker thread is also called worker thread, in order not to affect the UI thread's long-time task processing caused by the interface operation blocking, improve the user experience, open to consider opening a worker thread to complete the complex task, the task can be finished after processing to let it exit immediately also can let it continue to wait for new tasks, see the specific needs. A worker thread that does not exit while the task is finished and waits is in fact not much different from the UI thread, and the worker thread can implement a task queue on its own, and then continue to get the task to achieve the effect of the UI thread.
Regardless of the operating system, the UI thread and the worker thread will inevitably face the problem of thread synchronization, where synchronous execution is not the concept of "object state synchronization", but rather "serialization" of threads, such as thread A to wait for thread B to complete a specific task before executing a subsequent code snippet , of course, can also be achieved through the "Object state synchronization" way to achieve this effect, but it will be more troublesome.
In Windows systems, for example, when the worker thread finishes processing the results, it needs to return the results to the UI thread so that the interface can update the state of the display, in several ways:
1. Call Api::sendmessage directly at the worker thread execution point, send messages and accompanying parameters to the message queue of the UI thread, get processing from the message pump after the UI thread resumes from the suspended state, and if there are no other messages for the current message pump, process the message immediately. Otherwise, it waits until the other message is processed, and the worker thread waits for the message to be processed, and the UI thread finishes processing the message before it continues to execute;
2. Invoke the API directly at the worker thread execution point::P ostmessage, as with SendMessage, except that this is the worker thread that does not wait for the result to be processed and continues to go down, or asynchronously. If the PostMessage has parameters, then it has to be handled with care, just like normal thread asynchronous processing, the object must be unlocked, unless the accompanying parameter is a temporary object allocated from the heap, the UI thread is responsible for releasing the message before it is processed, but this involves the memory request between the modules, the release problem, Well, the program is directly core dump.
The 3.worker thread directly stores the result in a place that the UI thread can access, waits until the UI thread executes until it needs to use the result, and locks the object, making it difficult to deadlock.
The above 3 methods, regardless of which, the processing is very troublesome, although the first method is relatively simple, but write code to still feel cumbersome, to first define a mutual understanding of the message (also consider whether the message will conflict, consider using RegisterWindowMessage), Define the message handler, and then add the message map macro, and the code looks less fluent in sequential execution, where the code is to jump in and out of the way, and no matter how many synchronization messages need to be synchronized, it will be more difficult to maintain for a long time.
After a period of contact with this thread "pseudo-sync", it is natural to resent this approach and begin to think about the question of why the operating system does not provide a thread-switching API for calls. After waiting for a serious understanding of how threading works, it is naïve to discover this idea.
Usually a thread is scheduled to run by the operating system because it conforms to the current priority configuration, and the thread has code that needs to be executed (it seems to be less reasonable and can not be figured out), the most straightforward is the function call (no matter the global function or the constructor ...). ), since it is a function call that there must be arguments, variables into the stack out of the stack, each thread is suspended, in order to resume execution after the state can continue to execute, it is necessary that a thread corresponding to a line stacks, to this thread between each other, each in their own acres of three points on the ground work. Then consider the thread "serialization" problem, if the system to provide the thread switching API, then the worker thread needs to synchronize with the UI thread must have the UI thread to switch to the thread stack owned by the worker thread, otherwise how to access those variables, parameters in the worker thread, After the UI thread switches over, what to do with the previously reserved field, if the stack is a copy, then the UI thread copies it over to the top of the stack, what if the stack does not have enough space to use. And there are all sorts of reasons that I haven't been able to touch, and it's too high a price to be sure to do that.
UI Threads and worker threads