Not calling CloseHandle() on an ended thread HANDLE: is this a sin ?

Posted on 2006-04-21
Last Modified: 2013-11-20
Ah hello.

I create threads like this:

void CMyClass::CreateThread()
      //...other none-relevant stuff

      // First I make sure there is no thread already running in m_hThread, if there is, return (code not shown)

      CWinThread* pThread = AfxBeginThread(ThreadFunc, (LPVOID*)pThreadData, THREAD_PRIORITY_LOWEST,
            0, CREATE_SUSPENDED);

      ::DuplicateHandle (GetCurrentProcess (), pThread->m_hThread, GetCurrentProcess (), &m_hThread,

where m_hThread is a HANDLE member of CMyClass.  Now, according to Jeff Prosise's "Programming Windows with MFC" book, if I take this route to create a thread, I need to explicitly call ::CloseHandle(), passing the HANDLE to my thread.

I don't currently do this.

The thing is, I don't create my thread in a GUI, so to speak.  I have a standard class in a DLL that clients call.  The thread posts messages to any client GUI, if they provide the thread with a HWND (it is all standard stuff).  The only times I know that a thread is ended are

1) the client calls CMyClass::StopTask(), which stops the thread by setting an event that the thread periodically checks.  StopTask() then waits on the thread handle m_hThread

::WaitForSingleObject(m_hThread, INFINITE);
// If we get to here, we know the thread has fully ended...

2) The function ThreadFunc() reaching the end.

So, I know I can call ::CloseHandle() after ::WaitForSingleObject(m_hThread, INFINITE) has completed, but where can I call it when the thread finishes naturally ?  Could I call it at the end of ThreadFunc() ?  ( To do this, I would need to pass m_hThread to ThreadFunc(). )

It is worth noting that this code does not fail, even when creating thread after thread all in the same HANDLE m_hThread.  But still, I am not noticing any adverse effects from the absence of ::CloseHandle().  

Why do I need to call it then ?

Question by:mrwad99
    LVL 43

    Expert Comment

    Once your thread has finished its task it should inform the 'owner'.  So when the owner is informed you should be able to clean up the duplicate handle at that point.

    Why use CloseHandle.  (AFAIK this is correct)  HANDLEs are a resource.  Not closing the handle will result in a resource leak.  On Win NT based systems it is less of a problem then Win95 based systems - those had a much smaller limit on the avaiable handles for the system.  Use the handles up and the OP system can grind to a halt/crash.
    LVL 19

    Author Comment

    Hi Andy !

    >> Once your thread has finished its task it should inform the 'owner'.

    Yeah I know that.  Is what I suggested regarding passing the HANDLE to the thread function, and having the thread function call CloseHandle() just before returning ok or not ?

    LVL 43

    Accepted Solution

    excerpt from help:
    CloseHandle invalidates the specified object handle, decrements the object's handle count, and performs object retention checks. After the last handle to an object is closed, the object is removed from the system.

    Closing a thread handle does not terminate the associated thread. To remove a thread object, you must terminate the thread, then close all handles to the thread.

    I think you should be OK doing what you suggested, a HANDLE is not thread specific or anything like that.
    LVL 19

    Author Comment

    Thanks Andy !

    Any good with design patterns ? http:Q_21821996.html if you are :)
    LVL 43

    Expert Comment

    <Any good with design patterns ?>

    I had a look at the question  the other day.  I'll have to check the link out before I can answer that question.  I have had little formal programming training - mostly self tought.   ;-)

    Featured Post

    Top 6 Sources for Identifying Threat Actor TTPs

    Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

    Join & Write a Comment

    Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
    Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
    This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
    Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…

    728 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    19 Experts available now in Live!

    Get 1:1 Help Now