Citation :
The best approach to terminate threads gracefully is either to use a wait condition which includes extra wait events that can always be satisfied by a controlling thread, or to use alertable waits: Sleep calls : Replace Sleep function calls with a WaitForSingleObject function with a controlling object (probably an event) specified as the object to wait for and the sleep time as the timeout. The controlling thread ends the sleep early by signaling the controlling object. This would indicate to the thread that something needs to be done (cleanup). WaitForSingleObject : Replace the single object wait to a wait for two objects--the original object and an extra object (probably an event) that can control ending the wait. The WaitForMultipleObjects function would be used, specifying FALSE for fWaitAll, which would allow a controlling thread to set to event to end the wait. The thread code would detect that this event was signaled and would know that it needs to clean up. WaitForMultipleObjects : This is straight forward if the wait was for any single object to become signaled (fWaitAll was FALSE). Just add the control event as in the case of the single-object wait. For a multiple-object wait, there is no easy answer because the WaitForMultipleObjects function cannot be asked to wait for one set of objects to become signaled or another. Jeffrey Richter wrote a column in Microsoft Systems Journal (January, 1997) that discusses an approach of using alertable waits to create an API that allows you to accomplish this. It might be easier to use alertable waits in that you do not need to add an event. This method also affords extra flexibility in that any extra work can be queued up for the waiting thread. To use this method, use the alertable version of the synchronization functions ( WaitForSingleObjectEx , WaitForMultipleObjectsEx , MsgWaitForMultipleObjectsEx , SignalObjectAndWait , SleepEx ), and specify that the thread is alertable (bAltertable set to TRUE). The controlling thread now can specify that the thread should perform cleanup by queuing a user-mode APC by using the QueueUserAPC function.
|