none
CreateThread vs _beginthreadex

    Question

  • Hello.

    There is a hot discussion on one Russian developers forum about correct threads creation. _beginthreadex is more correct way because it initializes CRT for the newly created thread.

    But there is one great "BUT"!!!

    For example we have any callback function which uses CRT (like an exported function from dll). This function could be invoked from any thread including threads, that was created via CreateThread (i.e. CRT was not initialized for this thread). So this call can cause an undefined behaviour! But there is not way to determine CRT initialization status and initialize CRT manually

     

    It looks like a potential source of great troubles.

    Tuesday, February 06, 2007 10:25 AM

Answers

  • http://support.microsoft.com/default.aspx/kb/104641

    That should pretty much settle the score.

    Thursday, February 08, 2007 3:57 PM
    Moderator
  •  Alexander Stoyan wrote:

    A thread in an executable that calls the C run-time library (CRT) should use the _beginthread and _endthread functions for thread management rather than CreateThread and ExitThread; this requires the use of the multi-threaded version of the CRT.

    That looks like an old artifact to me. There's no longer any difference between the previously multithreaded and singlethreaded CRT libraries. In either case, the documentation should be clearer on what the actual difference is. Send a mail to the Platform SDK team, or bump this thread long enough for them to notice the argument.

    Thursday, February 08, 2007 3:13 PM
    Moderator
  •  einaros wrote:
     Alexander Stoyan wrote:

    A thread in an executable that calls the C run-time library (CRT) should use the _beginthread and _endthread functions for thread management rather than CreateThread and ExitThread; this requires the use of the multi-threaded version of the CRT.

    That looks like an old artifact to me. There's no longer any difference between the previously multithreaded and singlethreaded CRT libraries. In either case, the documentation should be clearer on what the actual difference is. Send a mail to the Platform SDK team, or bump this thread long enough for them to notice the argument.

    Ok. Thanks.

    Thursday, February 08, 2007 3:21 PM

All replies

  • I CAN`T BELIEVE!

    I asked this question on many forums. But I still have no an answer!

    I was right, it looks like a potential source of great troubles.

    Thursday, February 08, 2007 1:35 PM
  • ASFAIK CRT functions are calling Win32 functions for getting work done.

    If you
    could dig into the crt\src\threadex.c file, you can see how _beginthreadex has been written. It's internally calling CreateThread function.

    You can check this blog post by Visual C++ Team to know more about CRT initialization.

    Thursday, February 08, 2007 2:18 PM
  • Its not clear.  _beginthreadex and _beginthread wrap CreateThread, but do some other stuff.  You can step through _beginthreadex since the CRT sources are shipped with Visual Studio.  It calls an internal function _threadstart (which wraps your real thread entry procedure), and this function touches the "thread local store" (TLS), making that the point of possible behavior differences.  I don't see anything major going on here though: I see locale-related stuff, and I also see a case where special FP initialization occurs, but I don't know what scenario requires them.   

    If you have differences between calling _beginthreadex or CreateThread, I would look to see if they have anything to do with the things that the things that happen in _threadstart.

    Brian

    Thursday, February 08, 2007 2:19 PM
    Moderator
  • Sarath, that blog post does not mention threads whatsoever, so it is not helpful here.
    Thursday, February 08, 2007 2:21 PM
    Moderator
  •  Brian Kramer wrote:

    Its not clear.  _beginthreadex and _beginthread wrap CreateThread, but do some other stuff.  You can step through _beginthreadex since the CRT sources are shipped with Visual Studio.  It calls an internal function _threadstart (which wraps your real thread entry procedure), and this function touches the "thread local store" (TLS), making that the point of possible behavior differences.  I don't see anything major going on here thoug: I see locale-related stuff, and I also see a case where special FP initialization occurs, but I don't know what scenario requires them.   

    If you have differences between calling _beginthreadex or CreateThread, I would look to see if they have anything to do with the things that the things that happen in _threadstart.

    Brian

    But MSDN says:

    A thread in an executable that calls the C run-time library (CRT) should use the _beginthread and _endthread functions for thread management rather than CreateThread and ExitThread; this requires the use of the multi-threaded version of the CRT.

    It is not for no particular reason, Isn`t it?

    Thursday, February 08, 2007 2:48 PM
  • I think that statement is a bit silly, because 99.99% C/C++ apps in Visual Studio link against the C-Runtime, and it's hard not to call into it.  Based on what I saw, I believe there are cases where behavior can differ, but I don't know what.  If I ever start a blog, it'll be an interesting topic.
    Thursday, February 08, 2007 2:55 PM
    Moderator
  •  Brian Kramer wrote:
    I think that statement is a bit silly, because 99.99% C/C++ apps in Visual Studio link against the C-Runtime, and it's hard not to call into it.  Based on what I saw, I believe there are cases where behavior can differ, but I don't know what.  If I ever start a blog, it'll be an interesting topic.

    But 00.01% has mantained. I think this value is much greater because here works simply logic: "If CreateThread function is exists and documented then somebody will call it!". And then troubles are quite possible.

    Thursday, February 08, 2007 3:10 PM
  •  Alexander Stoyan wrote:

    A thread in an executable that calls the C run-time library (CRT) should use the _beginthread and _endthread functions for thread management rather than CreateThread and ExitThread; this requires the use of the multi-threaded version of the CRT.

    That looks like an old artifact to me. There's no longer any difference between the previously multithreaded and singlethreaded CRT libraries. In either case, the documentation should be clearer on what the actual difference is. Send a mail to the Platform SDK team, or bump this thread long enough for them to notice the argument.

    Thursday, February 08, 2007 3:13 PM
    Moderator
  •  einaros wrote:
     Alexander Stoyan wrote:

    A thread in an executable that calls the C run-time library (CRT) should use the _beginthread and _endthread functions for thread management rather than CreateThread and ExitThread; this requires the use of the multi-threaded version of the CRT.

    That looks like an old artifact to me. There's no longer any difference between the previously multithreaded and singlethreaded CRT libraries. In either case, the documentation should be clearer on what the actual difference is. Send a mail to the Platform SDK team, or bump this thread long enough for them to notice the argument.

    Ok. Thanks.

    Thursday, February 08, 2007 3:21 PM
  •  Alexander Stoyan wrote:

    But MSDN says:

    A thread in an executable that calls the C run-time library (CRT) should use the _beginthread and _endthread functions for thread management rather than CreateThread and ExitThread; this requires the use of the multi-threaded version of the CRT.

    It would have helped to include that in the original question. I knew that I had seen that but I could not remember where and did not want to look for it.
    Thursday, February 08, 2007 3:23 PM
  •  Brian Kramer wrote:
    I think that statement is a bit silly, because 99.99% C/C++ apps in Visual Studio link against the C-Runtime, and it's hard not to call into it.  Based on what I saw, I believe there are cases where behavior can differ, but I don't know what.  If I ever start a blog, it'll be an interesting topic.
    I agree, until I think about it. Note that it says thread, not application. I don't know how to ensure that a thread does not call the CRT, but it seems it is possible.
    Thursday, February 08, 2007 3:26 PM
  •  Simple Samples wrote:
     Alexander Stoyan wrote:

    But MSDN says:

    A thread in an executable that calls the C run-time library (CRT) should use the _beginthread and _endthread functions for thread management rather than CreateThread and ExitThread; this requires the use of the multi-threaded version of the CRT.

    It would have helped to include that in the original question. I knew that I had seen that but I could not remember where and did not want to look for it.

     

    Anyway can I be sure that my exported function from dll will be safe independently of thread where it will work? Is there any guarantee?

    Thursday, February 08, 2007 3:34 PM
  •  Simple Samples wrote:
     Brian Kramer wrote:
    I think that statement is a bit silly, because 99.99% C/C++ apps in Visual Studio link against the C-Runtime, and it's hard not to call into it.  Based on what I saw, I believe there are cases where behavior can differ, but I don't know what.  If I ever start a blog, it'll be an interesting topic.

    I agree, until I think about it. Note that it says thread, not application. I don't know how to ensure that a thread does not call the CRT, but it seems it is possible.

    #include <MyCRTFreeSTLVector>

    DWORD __stdcall* foo(void*) { /* vectorstuff */ return 0; }

    CreateThread(..., foo, 0, ...);

    There are plenty of good CRT replacements out there. I don't really see any use for avoiding it in just one thread, though. Again; an odd piece of information shared by MSDN, and if the multithreaded/singlethreaded CRT aspect is the only one, it seems like a complete waste of bandwidth.

    Thursday, February 08, 2007 3:42 PM
    Moderator
  •  einaros wrote:
     Alexander Stoyan wrote:

    A thread in an executable that calls the C run-time library (CRT) should use the _beginthread and _endthread functions for thread management rather than CreateThread and ExitThread; this requires the use of the multi-threaded version of the CRT.

    That looks like an old artifact to me. There's no longer any difference between the previously multithreaded and singlethreaded CRT libraries. In either case, the documentation should be clearer on what the actual difference is. Send a mail to the Platform SDK team, or bump this thread long enough for them to notice the argument.

    I think that is saying two or more things; specificly that:

    • _beginthread and _endthread functions need to be used
    • the _beginthread and _endthread functions require multithreaded runtime libraries

    Eventhough it is not necessary to state a requirement for multithreaded runtime libraries for VC 2005, I assume that the need for _beginthread and _endthread functions still exist for the reason stated.

    Thursday, February 08, 2007 3:43 PM
  •  Alexander Stoyan wrote:

    Anyway can I be sure that my exported function from dll will be safe independently of thread where it will work? Is there any guarantee?

    If you're worried, stick with _beginthread(ex). I don't think I'd put much thought into it at the moment. There'd be plenty of noise here if CreateThread actually *did* mess up bad with the new thread-indifferent CRT libraries.

    Thursday, February 08, 2007 3:45 PM
    Moderator
  •  Alexander Stoyan wrote:
    Anyway can I be sure that my exported function from dll will be safe independently of thread where it will work? Is there any guarantee?
    I think that is outside the scope of this forum. There are many things that need to be done to ensure that software is thread-safe.
    Thursday, February 08, 2007 3:45 PM
  •  Simple Samples wrote:
     einaros wrote:
     Alexander Stoyan wrote:

    A thread in an executable that calls the C run-time library (CRT) should use the _beginthread and _endthread functions for thread management rather than CreateThread and ExitThread; this requires the use of the multi-threaded version of the CRT.

    That looks like an old artifact to me. There's no longer any difference between the previously multithreaded and singlethreaded CRT libraries. In either case, the documentation should be clearer on what the actual difference is. Send a mail to the Platform SDK team, or bump this thread long enough for them to notice the argument.

    I think that is saying two or more things; specificly that:

    • _beginthread and _endthread functions need to be used
    • the _beginthread and _endthread functions require multithreaded runtime libraries

    Eventhough it is not necessary to state a requirement for multithreaded runtime libraries for VC 2005, I assume that the need for _beginthread and _endthread functions still exist for the reason stated.

    Interestingly, the text *used to be*:

    A thread in an executable that is linked to the static C run-time
    library (CRT) should use _beginthread and _endthread for thread
    management rather than CreateThread and ExitThread. Failure to do so
    results in small memory leaks when the thread calls ExitThread.

    Well actually it still says that, in the ExitThread docs.

    Thursday, February 08, 2007 3:51 PM
    Moderator
  • http://support.microsoft.com/default.aspx/kb/104641

    That should pretty much settle the score.

    Thursday, February 08, 2007 3:57 PM
    Moderator