Alex Rivera | Logout

Windows threading: _beginthread vs _beginthreadex vs CreateThread C++

Asked 2008-12-01T17:20:57.130
141

What's a better way to start a thread, _beginthread, _beginthreadx or CreateThread?

I'm trying to determine what are the advantages/disadvantages of _beginthread, _beginthreadex and 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.

Cheers!

Update: 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?

Edit
Report

3 Answers

106

CreateThread() is a raw Win32 API call for creating another thread of control at the kernel level.

_beginthread() & _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).

answered 2008-12-01T17:29:57.843
17

This is the code at the core of _beginthreadex (see crt\src\threadex.c):

    /*
     * Create the new thread using the parameters supplied by the caller.
     */
    if ( (thdl = (uintptr_t)
          CreateThread( (LPSECURITY_ATTRIBUTES)security,
                        stacksize,
                        _threadstartex,
                        (LPVOID)ptd,
                        createflag,
                        (LPDWORD)thrdaddr))
         == (uintptr_t)0 )
    {
            err = GetLastError();
            goto error_return;
    }

The rest of _beginthreadex initializes per-thread data structure for CRT.

The advantage of using _beginthread* is that your CRT calls from thread will work correctly.

answered 2008-12-01T18:33:16.017
6

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.

answered 2008-12-01T19:35:30.600

Your Answer