How to use _beginthread and endthread correctly

I'm used to working with the good old WinAPI call CreateThread()

and checking the state of the thread using a wait function, for example WaitForSingleObject()

. When the stream of the stream is signaled with WAIT_OBJECT_0

, I close it usingCloseHandle().

I recently decided to upgrade to beginthread

and somehow avoid the risks of uninitialized crt and accidental memory leaks that can happen.

Doing this confused me.

  • What is the purpose endthread()

    ? why, when i call CloseHandle()

    in the main function, after execution the thread CloseHandle()

    crashes with an invalid handle?
  • Should I ever close the returned handle beginthread

    ?
  • endthread

    As I understood it is automatically called by the thread when my function goes out of scope, so should I call it anyway just before going out of scope?
  • According to msdn, endthread is already calling CloseHandle()

    1. From where the thread gets a reference / instance to its handle. 2. If I insist on using it endthread()

    , should it be the last command in the stream?

thank

EDIT: The MSDN document describing the leaks is here .

+3


source to share


1 answer


As pointed out in the comments by David Hefferman, you can simply change your code to use CreateThread. The Visual C ++ Runtime (CRT) automatically initializes the CRT for each data stream the first time you use a function that uses the stream data.

The CRT also automatically frees thread data on thread, so using CreateThread will not cause memory leaks. There is one exception, if all of the following conditions are true, then the stream data will not be automatically freed:

  • You are creating an executable, not a DLL
  • You are referencing the static version of the CRT library (LIBCMT.LIB) instead of the DLL version (MSVCRT.LIB)
  • The executable that you created runs under Windows XP (or earlier version of Windows).


Note that even if all of this is true in your case, the memory leak will not be significant unless you are building a durable application that creates and destroys hundreds of thousands of threads over its lifetime.

If you still want to use the CRT ( _beginthread

/ _beginthreadex

) stream creation functions , you should follow these guidelines:

  • Never use the returned descriptor _beginthread

    . With the _beginthread

    flow handle, it closes automatically when the flow exits, which can happen before it _beginthread

    even returns. You cannot safely use it with WaitForSingleObject, because the thread may have already exited before you call this function. If you want to use a stream descriptor for anything, use _beginthreadex

    instead.
  • You should never close the returned handle _beginthread

    . The CRT will do this automatically and, as described in the previous point, may do it before you get a chance.
  • You should always close the handle returned _beginthreadex

    when you no longer need it. The CRT will not do this automatically for you, so it is your own responsibility.
  • Do not call _endthread

    or _endthreadex

    unless you want to terminate the stream quickly and abnormally. Until the CRT frees its data down the stream, none of the C ++ destructors for any of the stream objects will be called. It behaves in a similar way to _exit

    terminating a process without calling destructors.
  • The normal means of terminating a stream should be to return from a function passed as an argument _beginthread

    or _beginthreadex

    . This will cause C ++ destructors to be called as a normal part of the function return.
+6


source







All Articles