What\'s a better way to start a thread, _beginthread
, _beginthreadx
or CreateThread
?
I\'m trying to determine what are the adv
There is no difference anymore between the both.
All comments about memory leaks etc are based on very old < VS2005 versions. I've done some stress testing years ago and could debunk this myth. Even Microsoft mixes the styles in their examples, almost never using _beginthread.
Regarding your updated question: "I've also read in a couple of places that I can't call WaitForSingleObject()
if I used _beginthread()
, but if I call _endthread()
in the thread shouldn't that work?"
In general, you can pass a thread handle to WaitForSingleObject()
(or other APIs that wait on object handles) to block until the thread has completed. But the thread handle created by _beginthread()
is closed when _endthread()
is called (which can be done explicitly or is done implicitly by the run time when the thread procedure returns).
The problem is called out in the documentation for WaitForSingleObject()
:
If this handle is closed while the wait is still pending, the function's behavior is undefined.
beginthreadex
gives you a thread HANDLE
for use in WaitForSingleObject
and friends. beginthread
doesn't. Don't forget to CloseHandle()
when you are done. The real answer would be to use boost::thread
or soon C++09's thread class.
You should use _beginthread
or _beginthreadex
to allow the C runtime library to do it's own initialization of the thread. Only C/C++ programmers need to know this as they should now the rules of using their own development environment.
If you use _beginthread
you do not need to call CloseHandle
as the RTL will do for you. This is why you cannot wait on the handle if you have used _beginthread
. Also _beginthread
leads to confusion if the thread function exits immediately (quickly) as the launching thread my be left holding an invalid thread handle to the thread it just launched.
_beginthreadex
handles can be used for wait but also require an explicit call to CloseHandle
. This is part of what makes them safe for using with wait. There other issue to make it completely foolproof is to always start the thread suspended. Check for success, record handle etc. The resume thread. This is required to prevent a thread from terminating before the launching thread can record its handle.
Best practice is to use _beginthreadex
, start suspended then resume after recording handle, wait on handle is OK, CloseHandle
must be called.
Compared to _beginthread
, with _beginthreadex
you can:
OpenThread
.CloseHandle
.The _beginthreadex
closely resembles CreateThread
, but the former is a CRT implementation and the latter a Windows API call. The documentation for CreateThread contains the following recommendation:
A thread in an executable that calls the C run-time library (CRT) should use the _beginthreadex and _endthreadex functions for thread management rather than
CreateThread
and ExitThread; this requires the use of the multi-threaded version of the CRT. If a thread created usingCreateThread
calls the CRT, the CRT may terminate the process in low-memory conditions.
CreateThread()
is Windows API call that is language neutral. It just creates OS object - thread and returns HANDLE to this thread. All windows applications are using this call to create threads. All languages avoids direct API call for obvious reasons:
1. You don't want your code be OS specific
2. You need to do some house keeping before calling API-like: convert parameters and results, allocate temporary storage etc.
_beginthreadex()
is C wrapper around CreateThread()
that accounts for C specific. It enables original single threaded C f-ns work in multithreaded environment by allocating thread specific storage.
If you don't use CRT you cannot avoid a direct call to CreateThread()
. If you use CRT, you must use _beginthreadex()
or some CRT string f-ns may not work properly prior VC2005.