Subj : Re: Can C++ local static objects be made thread safe? To : comp.programming.threads From : Gianni Mariani Date : Wed Feb 02 2005 07:40 pm Giancarlo Niccolai wrote: > David Hopwood wrote: > > >>Alexander Terekhov wrote: >> >>>Gianni Mariani wrote: >>>[...] >>> >>> >>>>GCC 4.0 will have it's bug fixed in this area. Other compilers seem to >>>>have bugs. >>> >>>It's not a bug. Synchronizing all static locals by default (in "MT >>>mode") is just silly. >> >>Not doing so makes C++ static locals (with nontrivial constructors) >>effectively unusable in MT programs. >> > > > That's incorrect. Correct threading techniques can actually make C++ static > locals (the correct term is "Construct on first use semantic", or COFU), > absolutely safe. Please describe how. Without imposing draconian restrictions (and almost impossible to enforce) on the use of static locals, how do you provide a mechanism to use them safely in a multi-threaded environment ? > > One (and the simplest) is to mathematically demonstrate that all the COFU > are called before any thread is started. In general, that is impossible. In general, it's also impossible if you load DLL's/DSO's dynamically (after main() is called). This may be ensured by calling all > the COFU from main() before starting the first thread, provider that > constructors that may require COFU before main() do not start threads > (which, IMHO, is a pointless, dangerous and useless thing to do even > without the COFU problem). Say goodbye to plugins ? > > Another is to use the COFU semantic to construct on first use MT aware > objects BEFORE starting any thread, i.e. to construct a global mutex before > there is the possibility to start any thread even from pre-main() code, and > then use those safely constructed objects to regulate pre-main MT. Even if > I would disagree with the need to have pre-main MT, this would exclude the > need to call all the COFU from main() before the first thread is started > (or to be otherwise sure that all the COFU are called). In general, it is somtimes impossible to know what parameters to pass to static local constructors until after your threads are started. > > Notice that having a COFU called from the static constructors and then also > from main() does nothing, just ensures that the object GET constructed, if > not during the static initializers, at least before a thread requires it. > > Notice also that the COFU semantic is needed JUST AND ONLY to avoid the > "static initialization order fiasco"; that is, COFUing is a "trick" to > avoid your program to break during startup if it ever needs objects to be > constructed that way. C++ experts advise against this technique, and > suggest to use the COFU ONLY if there isn't any other way to have your > program run. If you can, create the objects from main or thereafter, and > avoid using objects declared as global variable. If you can't (and you > should motivate this inability with some strong point), then use COFU to > prevent your program from crashing. Cfr. the C++ FAQ lite on this point. I'd like to know the C++ experts you're talking about. > > > Conclusion: Terekhov is right, as almost always. Having compilers preventing > you to do silly things is silly, especially if this "rescue" towards the > unaware programmers has a performance cost on correctly built programs. This is where I think we disagree. The whole purpose of a compiler is to save me from having to create code that I would otherwise have to write by hand. The question is where does that line fall. Since man hours cost significanly more that CPU hours, the more work I can get the compiler to do, the less cost my product will be and likely better, less buggy as well. .