How to suspend the main thread until the end of the second thread?
From http://www.codeproject.com/threads/waitthreadmsi.asp#xx441032xx
Ybbozman
Don't be frightened by thread, let's take a look at it;)
As a translation, I encountered a similar problem with YBbozman in VC . In the primary application (main process - actually still thread, the main thread can also be), when you click the "Find" button, I made me. The event of a search recursive search file - this event will be very slow, resulting in the significant interfacial redrawing, the CPU resource usage is very high, the reason is that the Windows preemptive multitasking will be the highest level of this main thread. Find file events are events as this primary thread being executed, and most of the CPUs will be given to find file events, while the operating rate of interface redrawing will become unpredictable.
Start a new working thread for this Find file event, is very efficient, looking for file events in new work threads, but the priority is not higher than the current main thread, which guarantees the interface redraw operation Normal, the problem is that I want to continue to execute some of the main threads after the finding file event is completed, which involves the problem between thread waiting - Wait (called synchronization -synchronization better), Ybbozman's question and I have something like this, and I look at how YBozman is how to wait for the thread.
Introduction
A few weeks ago, I need to make a dialog box as part of the MSI installer (Windows2000 software installation), and the code written to this must be released as a regular (rule) DLL. Whether this dialog is visible, depending on the result of the installation completion, that is, the function depends on another thread (the working thread is being performed here) is completed, and the thread is terminated after the installation is complete, and this conversation is finally displayed. frame.
solve
You must write two functions, the first void cmytestDialog :: PeekMessageloop () Get a message from the message queue:
Void CMYTESTDIALOG :: peekMessageloop ()
{
MSG msg;
While (PeekMessage (& MSG, NULL, NULL, NULL, PM_REMOVE))
{
TranslateMessage (& MSG);
DispatchMessage (& MSG);
}
}
The second, void cmytestdialog :: waitforthreadtoterminate (Handle Hthread) will indicate which thread needs to wait and further process:
Void CMYTESTDIALOG :: WaitForthReadtoterminate (Handle Hthread)
{
DWORD DWRET;
DO
{
DWRET = :: MsgwaitFormultipleObjects (1, & Hthread, False,
Infinite, QS_allInput);
IF (dwret! = WAIT_Object_0)
{
PeekMessageloop ();
}
} while ((dwret! = wait_object_0) && (dwret! = wait_failed);
}
Sample code
Suppose there is a button on the dialog, when the button is clicked, start starting the second thread, wait until the second thread is complete, we will continue the main thread down:
Void CMYTESTDIALOG :: Onbutton1 ()
{
m_pupdatethread = afxbeginthread (UpdatedEviceContent,
(LPVOID) this / *, thread_priority_below_normal * /);
IF (m_pupdatethread)
{
WaitForthReadtoterminate (m_pupdatethread-> m_hthread);
}
// do wherever you want after the action is finished
}
Ybbozman uses the API function of the synchronization between the thread when resolving this problem :: MsgwaitFormultiPleObjects function, is a signal-Semaphore (Note 1) synchronization function for waiting for an object (here you are thread T2 to wait). When the primary T2 signal is allowed to arrive (using a specific message -Message instructs the arrival of the signal state, the last parameter QS_allinput of :: msgWaitFormultiPleObjects specifies that all input messages can be reached as the signal state So returning, PeekMessageloop () will remove any of the window messages in the current running thread and all messages in the current runmessage to the current running thread, so iteratively calls: MsgWaitFormultiPleObjects, only new messages arrive After the function is returned; in addition, PeekMessageloop () is called again, iterates again: MsgwaitFormultiPleObjects, some system events are processed: for example, WM_PAINT messages for the window (Note: Even if the last parameter of PeekMessage is set to PM_Remove, PeekMessageloP () After the call, the WM_PAINT message will not be removed from the message queue). I have a lot, I am a little dizzy, then I will attribute: 1. :: msgwaitformultipleObjects iteration Wait for a specific message in the specified thread, when the thread ends :: MsgwaitFormultiPleObjects will return to WAIT_OBJECT_0 to indicate the end of the thread! II. PEEKMESSAGELOOP iteration Gets any window message in the current running thread and the message submitted by PostthReadMessage to the current running thread, call PeekMessageLoop Remove the message from the message queue There are two purposes: a. Call :: MsgwaitFormultiPleObjects must wait until a new message arrives after arrival; b. Update system events, this is a very useful function, which will prevent the message waiting process (ie iterated :: MsgwaitFormultipleObjects) exclusive CPU resources, without dealing with certain important system events: hardware input messages, window redraw, timing messages, etc.
MsgwaitFormultiPleObjects supports the synchronization of the object below:
Mutex Mutual Repel EVENT Event Semaphore Signal Process Process Thread Threads Critical Section In addition, the synchronization function between threads also has WaitForsingleObject, WaitFormultiPleObjects, and the use method is similar, except for the Critical Section (critical section). MsgwaitFormultiPleObjects is more used to wait for some special messages from synchronous objects.
Finally, the incorrect mistakes is inevitable, please ask someone to criticize the correct. Note 1: Dutch famous computer scientist Dijkstra abstraction as a synchronous problem of a process or thread, Dijkstra has fallen away from the Netherlands on August 6, 2002.
Reference: MSDN Help Document.