What's a better way to start a thread,
I'm trying to determine what are the advantages/disadvantages of
CreateThread. All of these functions return a thread handle to a newly created thread, I already know that CreateThread provides a little extra information when an error occurs (it can be checked by calling
GetLastError)... but what are some things I should consider when I'm using these functions?
I'm working with a windows application, so cross-platform compatibility is already out of the question.
I have gone through the msdn documentation and I just can't understand, for example, why anybody would decide to use _beginthread instead of CreateThread or vice versa.
OK, thanks for all the info, 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? What's the deal there?
CreateThread() is a raw Win32 API call for creating another thread of control at the kernel level.
_beginthreadex() are C runtime library calls that call
CreateThread() behind the scenes. Once
CreateThread() has returned,
_beginthread/ex() takes care of additional bookkeeping to make the C runtime library usable & consistent in the new thread.
In C++ you should almost certainly use
_beginthreadex() unless you won't be linking to the C runtime library at all (aka MSVCRT*.dll/.lib).
There are several differences between
_beginthreadex() was made to act more like
CreateThread() (in both parameters and how it behaves).
As Drew Hall mentions, if you're using the C/C++ runtime, you must use
_beginthreadex() instead of
CreateThread() so that the runtime has a chance to perform it's own thread initialization (setting up thread local storage, etc.).
In practice, this means that
CreateThread() should pretty much never be used directly by your code.
The MSDN documents for
_beginthreadex() have quite a bit of detail on the differences - one of the more important is that since the thread handle for a thread created by
_beginthread() gets closed automatically by the CRT when the thread exits, "if the thread generated by _beginthread exits quickly, the handle returned to the caller of _beginthread might be invalid or, worse, point to another thread".
Here is what the comments for
_beginthreadex() in the CRT source have to say:
Differences between _beginthread/_endthread and the "ex" versions: 1) _beginthreadex takes the 3 extra parameters to CreateThread which are lacking in _beginthread(): A) security descriptor for the new thread B) initial thread state (running/asleep) C) pointer to return ID of newly created thread 2) The routine passed to _beginthread() must be __cdecl and has no return code, but the routine passed to _beginthreadex() must be __stdcall and returns a thread exit code. _endthread likewise takes no parameter and calls ExitThread() with a parameter of zero, but _endthreadex() takes a parameter as thread exit code. 3) _endthread implicitly closes the handle to the thread, but _endthreadex does not! 4) _beginthread returns -1 for failure, _beginthreadex returns 0 for failure (just like CreateThread).
Update Jan 2013:
The CRT for VS 2012 has an additional bit of initialization performed in
_beginthreadex(): if the process is a "packaged app" (if something useful is returned from
GetCurrentPackageId()) the runtime will initialize the MTA on the newly created thread.