CreateThread vs _beginthreadex
-
Tuesday, February 06, 2007 10:25 AM
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.
All Replies
-
Thursday, February 08, 2007 1:35 PM
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 2:18 PMASFAIK 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:19 PMModerator
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:21 PMModeratorSarath, that blog post does not mention threads whatsoever, so it is not helpful here.
-
Thursday, February 08, 2007 2:48 PM
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:55 PMModeratorI 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 3:10 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. 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:13 PMModerator
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:21 PM
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:23 PMIt 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.
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. -
Thursday, February 08, 2007 3:26 PMI 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.
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. -
Thursday, February 08, 2007 3:34 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:42 PMModerator
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.
| einaros wrote: | ||||||
|
- _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.
| Alexander Stoyan wrote: | |
|
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.
| Alexander Stoyan wrote: | |
|
| Simple Samples wrote: | |||||||||
|
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.

