Suppose you want to organize the protection of an arbitrary code by a local static mutex:

void MyClass::myMethod() { static QMutex mutex; mutex.lock(); // защищённый код ... mutex.unlock(); } 

As far as I know, if instead of QMutex is a different local static type (for example, QString ), a “race” can easily happen and, say, two competing streams will create two copies of the object.

Despite the fact that Qt help for QMutex indicates that all methods are thread-safe, there is no certainty that this is true for its constructor.

Would it be in the context of MyClass::myMethod() creating a mutex object at the first call is thread-safe?

  • one
  • @kff, that is, as I understand it, they write that it seems to be safe to create static local variables multithreadedly? Generally any type, and not just mutexes? At Habré while writing another. Maybe the truth is already out of date? - alexis031182

1 answer 1

Starting with C ++ 11, initialization of static variables is thread-safe ( §6.7 ):

Otherwise, such a variable is initialized; such a variable is considered initialized upon completion of its initialization. It will be your intention. If you control the declaration while the variable is being initialized,


For earlier standards this was not guaranteed, although some compilers provided such protection (for example, GCC).

Consider the QMutex constructor:

 QMutex::QMutex(RecursionMode mode) { d_ptr.store(mode == Recursive ? new QRecursiveMutexPrivate : 0); } 

Qt makes extensive use of the Pimpl idiom, d_ptr is just a pointer to the implementation and is of type QBasicAtomicPointer<QMutexData> . With multi-thread access to the constructor, there may be cases when the QRecursiveMutexPrivate object will be constructed several times, which will lead to memory leaks. If the mutex is non-recursive, then the constructor is thread-safe.

Another more serious problem is race condition : for example, two threads A and B start initializing the mutex variable, thread A completes initialization and calls the lock() function, control is passed to thread B , which in turn completes initialization, which results in to indefinite behavior.

  • Not quite understood. On the one hand: "the concurrent execution", and on the other hand you write that thread B , like stream A , also completes the initialization of the mutex variable. Does this mean that thread B still won't wait until A fully constructs the mutex object? - alexis031182
  • @ alexis031182 All that after quotations in relation to earlier standards. I tried to visually separate - Pavel Parshin
  • Saw now, thank you very much. - alexis031182