Subj : Re: Can C++ local static objects be made thread safe? To : comp.programming.threads From : Giancarlo Niccolai Date : Sat Feb 05 2005 02:04 am Marcin 'Qrczak' Kowalczyk wrote: > >> and that some correct MT code may get broken. > > but not with this. Please show such code. > Producer and Consumer are two MT classes. Queue is a synchronization devices that allows only a limited set of elements to be pushed in it; when it's full, the pushing thread will block; when it's empty, the popping thread will block. So (pseudocode): Queue *the_queue; Class Producer { .... Producer() { for i = 1 to 100: the_queue->push( startup_data[i] ); } }; Class Consumer { .... Consumer() { for i = 1 to 100: save_data[i] = the_queue->pop(); } }; void *thread1( void *) { static Producer p; .... return 0; } void *thread2( void *) { static Consumer c; .... return 0; } int main( ... ) { *the_queue = new Queue( MAX_SIZE ); // much less than 100 start_thread( thread1 ); start_thread( thread2 ); ... } So, without any static initializer constraint this program works. Funny, it works also if you use a static the_queue; object, as the threads are mathematically started after than non-PODS statics are initialized. Also, it works regardless the nature of SomeClass, as there is the mathematical certainty that they are created by one thread (the producer) before the consumer has ever the ability to know about their existence. Of course, Queue must be a traditionally locking queue. But if I add a mutex for static initializers at Consumer c and at Producer p points, the constructor of the consumer will still not be exited when it will wait for p to receive the initialization data, blocking on MAX_SIZE. But P can't go, as it is locked waiting for the construction of C to release the static initializer mutex. Moreover, I don't know what to do with SomeClass...what the compiler would say about them (doesn't really matters, but what if SomeClass needs some static data in its class to be set up)? This is exactly the POSIX standard REQUIRES that mutex hare held in critical region ACCESSING DATA and for no more the time NEEDED TO ACCESS THE DATA: descending into functions that may do many things, as do blocking calls, requesting other mutexes, stop the thread etc. while holding a mutex is just madness. As I said, C# made it fine and you can effectively hold C# mutexes while doing any sort of things: but that's because their mutex construct is NOT an OS mutex, but a managed entity that can be checked against deadlocks or early termination by the VM linearization of some parallelism, as I know you know. But you are required not to do that with OS level mutexes, and the above class of problems explains why this requirement is made. Bests, Giancarlo. .