As stated in the comments by David Hefferman you can simply change your code back to using CreateThread. The Visual C++ runtime (CRT) will automatically initialize the CRT's per thread data the first time you use a function that uses the per thread data.
The CRT will also automatically free the per thread data when a thread ends, so using CreateThread won't cause memory leaks. There is one exception, if all of the following conditions are true then per thread data isn't automatically freed:
- You're building an executable, not a DLL
- You're linking against the static version of the CRT library (LIBCMT.LIB) instead of the DLL version (MSVCRT.LIB)
- The executable you built is run under Windows XP (or an earlier version of Windows).
Note that even if all this true in your case, the memory leak isn't going to be significant unless you're creating a long lived application that creates and destroys hundreds of thousands of threads over its life time.
If you still want to use the CRTs thread creation functions (_beginthread
/_beginthreadex
) you should follow these guidelines:
- Never use the handle returned by
_beginthread
. With _beginthread
the thread handle is automatically closed when the thread exits, which can potentially happen before _beginthread
even returns. You can't use it with WaitForSingleObject safely because the thread might have already exited before you call this function. If you want to use the thread handle for anything use _beginthreadex
instead.
- You should never close the handle returned by
_beginthread
. The CRT will do it automatically, and as described in the previous point, may do so before you have chance to.
- You should always close the handle returned by
_beginthreadex
when you no longer need it. The CRT won't do this automatically for you, so it's your own responsibility.
- Don't call
_endthread
or _endthreadex
unless you want to quickly and abnormally terminate the thread. While the CRT will free its own per thread data, none of the C++ destructors for any of the thread's objects will be called. It behaves similarly to how _exit
ends the process without calling destructors.
- The normal means of ending a thread should be by returning from the function passed as an argument to
_beginthread
or _beginthreadex
. This will result in C++ destructors being called as a normal part of the function return.