views:

148

answers:

3

At some point I remember reading that threads can't be safely created until the first line of main(), because compilers insert special code to make threading work that runs during static initialization time. So if you have a global object that creates a thread on construction, your program may crash. But now I can't find the original article, and I'm curious how strong a restriction this is -- is it strictly true by the standard? Is it true on most compilers? Will it remain true in C++0x? Is it possible for a standards conforming compiler to make static initialization itself multithreaded? (e.g. detecting that two global objects don't touch one another, and initializing them on separate threads to accelerate program startup)

Edit: To clarify, I'm trying to at least get a feel for whether implementations really differ significantly in this respect, or if it's something that's pseudo-standard. For example, technically the standard allows for shuffling the layout of members that belong to different access specifiers (public/protected/etc.). But no compiler I know of actually does this.

+6  A: 

What you're talking about isn't strictly in the language but in the C Run Time Library (CRT).
For a start, if you create a thread using a native call such as CreateThread() on windows then you can do it anywhere you'd like because it goes straight to the OS with no intervention of the CRT.
The other option you usually have is to use _beginthread() which is part of the CRT. There are some advantages to using _beginthread() such as having a thread-safe errno. Read more about this here. If you're going to create threads using _beginthread() there could be some issues because the initializations needed for _beginthread() might not be in place.

This touches on a more general issue of what exactly happens before main() and in what order. Basically you have the program's entry point function which takes care of everything that needs to happen before main() with Visual Studio you can actually look at this piece of code which is in the CRT and find out for yourself what exactly's going on there. The easyest way to get to that code is to stop a breakpoint in your code and look at the stack frames before main()

shoosh
Thanks, this gives me some idea of what the situation is like on Windows with MSVC. I'm still curious about other platforms though, and it doesn't really answer whether it's safe on Windows or not (does _beginthread() actually rely on any initialization that may not have taken place yet?).
Joseph Garvin
I wish I knew this as well. The docs doesn't seem to mention it.
shoosh
+2  A: 

The underlying problem is a Windows restriction on what you can and cannot do in DllMain. In particular, you're not supposed to create threads in DllMain. Static initialization often happens from DllMain. Then it follows logically that you can't create threads during static initialization.

MSalters
A: 

As far as I can tell from reading the C++0x/1x draft, starting a thread prior to main() is fine, but still subject to the normal pitfalls of static initialization. A conforming implementation will have to make sure the code to intialize threading executes before any static or thread constructors do.

coppro