dushkin
dushkin

Reputation: 2101

Win32, MFC: Ending threads

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

Answers (4)

Steve
Steve

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

TWA
TWA

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

IInspectable
IInspectable

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

Steve
Steve

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

Related Questions