Reputation: 2101
I have a DLL which has a CWinThread based class called CWork. I create it using AfxBeginThread.
In this class I defined a procedure that will loop infinetly and perform a certain task. This procedure will be used as a thread by itself. I create it also using AfxBeginThread.
Now, when my DLL exits, I'd like to end the thread. This is because I have a crash on exit, and I am affraid that is the reason.
In addition, there is
Pseudo Code example:
class Cmain
Cmain::Cmain(){
pMyThread = AfxBeginThread(CWork - a CWinThread based Class);
}
UINT HandleNextVTSConnectionCommandProc(LPVOID pParam);
class CWork
CWork:CWork(){
AfxBeginThread(HandleNextVTSConnectionCommandProc, this);
}
UINT HandleNextVTSConnectionCommandProc(LPVOID pParam){
while(true){
dosomething();
sleep(2000);
}
}
My question is, what is the correct way of ending those 2 threads?
Thank you!
Upvotes: 4
Views: 2148
Reputation: 1810
Something like this should get you started:
HANDLE g_hThreadExitRequest = NULL;
UINT __cdecl ThreadFunction(LPVOID pParam)
{
AllocConsole();
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
for (int i=1; true; ++i)
{
CStringA count;
count.Format("%d\n", i);
WriteFile(hCon, (LPCSTR)count, count.GetLength(), NULL, NULL);
if (WaitForSingleObject(g_hThreadExitRequest, 1000) == WAIT_OBJECT_0)
break;
}
// We can do any thread specific cleanup here.
FreeConsole();
return 0;
}
void Go()
{
// Create the event we use the request the thread exit.
g_hThreadExitRequest = CreateEvent(
NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes
TRUE, // BOOL bManualReset
FALSE, // BOOL bInitialState
NULL // LPCTSTR lpName
);
// We create the thread suspended so we can mess with the returned CWinThread without
// MFC auto deleting it when the thread finishes.
CWinThread *pThread = AfxBeginThread(
&ThreadFunction, // AFX_THREADPROC pfnThreadProc
NULL, // LPVOID pParam
THREAD_PRIORITY_NORMAL, // int nPriority
0, // UINT nStackSize
CREATE_SUSPENDED , // DWORD dwCreateFlags
NULL // LPSECURITY_ATTRIBUTES lpSecurityAttrs
);
// Turn off MFC's auto delete "feature".
pThread->m_bAutoDelete = FALSE;
// Start the thread running.
pThread->ResumeThread();
// Wait 30 seconds.
Sleep(30*1000);
// Signal the thread to exit and wait for it to do so.
SetEvent(g_hThreadExitRequest);
WaitForSingleObject(pThread->m_hThread, INFINITE);
// Delete the CWinTread object since we turned off auto delete.
delete pThread;
// We're finished with the event.
CloseHandle(g_hThreadExitRequest);
g_hThreadExitRequest = NULL;
}
Upvotes: 1
Reputation: 12816
Set a flag instead of using while(true) to tell your thread when it should end. You could also use an event.
You should also wait for your thread to be complete before you exit, so you should use (in the main code, once you signal the thread to end):
WaitForSingleObject(thread_handle)
Upvotes: 2
Reputation: 51355
Create an event calling CreateEvent that is initially non-signaled. When your application terminates, signal this event (SetEvent) and wait for the thread to terminate (WaitForSingleObject on the thread handle).
Inside your thread function HandleNextVTSConnectionCommandProc
replace your while(true)
loop with
while(WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0)
Doing the above allows you to signal the thread to terminate from your application. The thread terminates, when it returns from its thread proc.
Upvotes: 4
Reputation: 1810
In general the correct way to end a thread is to ask it to finish and then wait for it to do so. So on Windows you might signal an event to ask the thread to finish up then wait on the thread HANDLE. Forcefully terminating a thread is almost always a misguided idea which will come back to haunt you.
Upvotes: 5