pHaze426
asked on
Using CEvent / CWinthread during thread termination
I'm writing a multithreaded MFC application (famous last words, I know). I have a main dialog based application that uses AfxBeginThread to launch a CWinthread-derived UI thread of my design. My question relates to how to properly terminate the thread when someone presses the cancel button in the main application dialog.
What I've tried so far is the following: I created a CEvent member variable within the CWinthread-derived class which I initially set to unsignalled. I have overridden OnCancel in the main dialog as follows:
CSomethingorother::OnCance l {
m_pMyThread->PostThreadMes sage(WM_BA ILOUT, 0, 0);
WaitForSingleObject(m_pMyT hread->m_e EndEvent, INFINITE);
CDialog::OnCancel();
}
When I catch the WM_BAILOUT message in my thread, I call PostQuitMessage. Then, in ExitInstance for the thread, I have:
m_eEndEvent.SetEvent();
This all seems to work just as I expect, but my question is this: Is there a possibility that after the event is signalled, my thread will finish terminating and get deleted before the calling thread (my dialog app) has a chance to properly "see" the event when it's still valid. In other words, am I running the risk of some later timing issues having it hang indefinitely? Is this the correct and thread-safe way to do things? The documentation for MFC's synchronization classes seems spotty to me and I'm not sure if they have some internal mechanisms for making sure things like this function correctly (in fact, I don't see how it could).
Any help would be greatly appreciated.
What I've tried so far is the following: I created a CEvent member variable within the CWinthread-derived class which I initially set to unsignalled. I have overridden OnCancel in the main dialog as follows:
CSomethingorother::OnCance
m_pMyThread->PostThreadMes
WaitForSingleObject(m_pMyT
CDialog::OnCancel();
}
When I catch the WM_BAILOUT message in my thread, I call PostQuitMessage. Then, in ExitInstance for the thread, I have:
m_eEndEvent.SetEvent();
This all seems to work just as I expect, but my question is this: Is there a possibility that after the event is signalled, my thread will finish terminating and get deleted before the calling thread (my dialog app) has a chance to properly "see" the event when it's still valid. In other words, am I running the risk of some later timing issues having it hang indefinitely? Is this the correct and thread-safe way to do things? The documentation for MFC's synchronization classes seems spotty to me and I'm not sure if they have some internal mechanisms for making sure things like this function correctly (in fact, I don't see how it could).
Any help would be greatly appreciated.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Guys,
This seems like a good methodology as opposed to using CEvent, but assuming I wanted to stick with that. I'm just unsure how a CEvent could be used in this manner, although it seems to be what they were designed for. The documentation for WaitForSingleObject suggests that it consumes no CPU time while waiting for the event to occurr. Does this register some sort of interrupt handler with the system for the event? If so, that might mean I don't have to worry about it.
This seems like a good methodology as opposed to using CEvent, but assuming I wanted to stick with that. I'm just unsure how a CEvent could be used in this manner, although it seems to be what they were designed for. The documentation for WaitForSingleObject suggests that it consumes no CPU time while waiting for the event to occurr. Does this register some sort of interrupt handler with the system for the event? If so, that might mean I don't have to worry about it.
The problem with using event is that your thread might be dead already, or maybe it never got kicked off in the first place.
In which case, your application will hang forever if your waiting on an event signal
In which case, your application will hang forever if your waiting on an event signal
I think you should modify the code, so it's not doing an infinite wait on the thread, and try to do a force kill on the thread if it takes too long.
CSomethingorother::OnCance
const int QtyOfRetries = 9;
DWORD result ;
for(int i = 0;i < QtyOfRetries;++i)
{
m_pMyThread->PostThreadMes
DWORD result = WaitForSingleObject(m_pMyT
if (WAIT_TIMEOUT != result) break;
}
if (WAIT_TIMEOUT == result)
{//Force kill the thread
}
CDialog::OnCancel();
}
That way your application doesn't hang if one thread hangs.