4

I'm reading the documentation about _beginthreadex and _endthreadex but there are a few things I don't understand.

Note that the documentation keeps documenting the "extended" and normal functions at the same time, but I'm not using _beginthread and _endthread; only their extended versions.


You can call _endthread or _endthreadex explicitly to terminate a thread; however, _endthread or _endthreadex is called automatically when the thread returns from the routine passed as a parameter. Terminating a thread with a call to endthread or _endthreadex helps to ensure proper recovery of resources allocated for the thread.

  • If _endthreadex is called automatically, how come calling it helps to ensure "proper recovery of resources"? It shouldn't make any difference whether I call it or not, or does it?

_endthread automatically closes the thread handle (whereas _endthreadex does not). Therefore, when using _beginthread and _endthread, do not explicitly close the thread handle by calling the Win32 CloseHandle API.

  • If _endthreadex does not close the handle, how come I shouldn't close it with CloseHandle?
  • All of my threads only voluntarily terminate by returning from their main function and are never forcefully terminated. According to the documentation, when this happens _endthreadex is called automatically.

    This though won't close the handle. Assuming that I do need to close it, notwithstanding with what is said above, how can I do that since at this point the thread is dead? Should I somehow close it from another thread? What happens if I leave it open?

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Andreas Bonini
  • 44,018
  • 30
  • 122
  • 156

2 Answers2

5

If _endthreadex is called automatically, how come calling it helps to ensure "proper recovery of resources"? It shouldn't make any difference whether I call it or not, or does it?

I think they meant this for the cases when you do not use a standard way of terminating your thread.

If _endthreadex does not close the handle, how come I shouldn't close it with CloseHandle?

You should close it with CloseHandle when using _endthreadex. The documentation says that only _endthread closes the handle (and therefore a CloseHandle call is superfluous).

All of my threads only voluntarily terminate by returning from their main function and are never forcefully terminated. According to the documentation, when this happens _endthreadex is called automatically.

Closing the thread handles from the thread that started it is a commonly-used solution. You should remember the handle and in appropriate place wait for the thread to finish (using WaitForSingleObject) and then close its handle. If you don't do that you will cause a leak of resources. That is usually not a big problem if you have a few threads but it is definitely not good practice.

Nathan Arthur
  • 8,287
  • 7
  • 55
  • 80
Karel Petranek
  • 15,005
  • 4
  • 44
  • 68
  • What happens if I close the handle in the thread's main function ? – Andreas Bonini Oct 16 '10 at 22:47
  • I guess that's an undefined behavior. It might work, it might leak, it might deadlock, it might crash. And worst of all - it can change any time and vary between different computers. – Karel Petranek Oct 16 '10 at 22:50
  • @KarelPetranek Could you explain why calling `CloseHandle` from within the thread would be undefined behavior? Can you provide a reference? The MSDN documentation for `CloseHandle` states that it does not terminate the thread, so I don't see any obvious reason why it should be UB from within the thread. – jamesdlin May 07 '14 at 22:13
  • @jamesdlin `The documentation for the functions that create these objects indicates that CloseHandle should be used when you are finished with the object, and what happens to pending operations on the object after the handle is closed. In general, 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.` and `To remove a thread object, you must terminate the thread, *then* close all handles to the thread` – Karel Petranek May 08 '14 at 10:14
  • @KarelPetranek To me, it seems analogous to typical `CreateProcess` usage where if the caller doesn't care about the returned process and thread handles, it immediately closes them. And given that `CloseHandle` does not remove the thread object, the thread itself should still be valid even if it was called on the handle to a running thread, regardless of which thread `CloseHandle` was called from. So in my interpretation, behavior should not be undefined, and at worst there might be a resource leak (but I don't think that's true either). – jamesdlin May 08 '14 at 10:44
  • @jamesdlin That really depends on the interpretation. I'd definitely consider closing the handle after the thread finishes a safer option. – Karel Petranek May 08 '14 at 11:15
0

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.

ref:https://stackoverflow.com/a/31257350/6364089

hxysayhi
  • 1,888
  • 18
  • 25