简体   繁体   中英

How to properly use _beginthread and endthread

I'm used to work with good old WinAPI call CreateThread() , and check thread's status using the waiting function, eg WaitForSingleObject() , Once thread thread is signaled with WAIT_OBJECT_0 , i close it using CloseHandle().

Recently I've decided to move to beginthread and somehow avoid the risks of uninitialized crt and accidental memory leaks that may happen.

Doing that got me confused.

  1. What's the exact purpose of endthread() ? why when i call CloseHandle() in the main function, after thread's execution, CloseHandle() crashes with invalid handle?
  2. Should i ever close the handle returned by beginthread ?
  3. endthread , As i understood is invoked automatically by the thread once my function goes out of scope, so should i call it anyway just before i get out of scope?
  4. According to msdn, endthread already calls CloseHandle() 1.From where does the thread obtain a reference / instance to its handle. 2. If i do insist on using endthread() , should it be the last command in the thread?

thanks

EDIT: MSDN paper describing the leaks, here .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM