PDA

View Full Version : Why is QMutex Thread Safe?



Kind Lad
20th February 2010, 08:17
Re: http://qt.nokia.com/doc/4.0/threads.html

At the above URL we are given the following example:



class Counter
{
public:
Counter() { n = 0; }

void increment() { QMutexLocker locker(&mutex); ++n; }
void decrement() { QMutexLocker locker(&mutex); --n; }
int value() const { QMutexLocker locker(&mutex); return n; }

private:
mutable QMutex mutex;
int n;
};



What makes this thread safe? I assume the QMutexLocker constructor is not atomic (I could be wrong). If two threads call increment, a QMutexLocker would be created. This will in part check to see that mutex is not currently locked. Is it not possible for both threads to call increment and both simultaneously begin to create a QMutexLocker, both QMutexLocker constructor calls simultaneously check the lock state of mutex, both simultaneously confirm that mutex is not currently locked, both lock mutex, both increment n, and then release. Ending up with the same non-thread safe issue you'd have if a mutex was not used at all.

Is a QMutexLocker more about lowering the chance of threading issues and not actually eliminating them? Perhaps I've overlooked something.

Kind Lad
20th February 2010, 08:18
This post should be deleted.

Kind Lad
21st February 2010, 18:46
Does nobody know the answer?

Coises
22nd February 2010, 04:46
What makes this thread safe?

Qt is open source; the details are in the source code.

A quick look shows that QMutex is implemented using platform-specific operating system calls and QAtomicInt, which in turn is implemented using platform/compiler-specific code (for example, some inline assembly code is used under Windows/MinGW). At that point it’s beyond my understanding, but that’s where you’ll have to look if you want to know, in detail, why it’s thread-safe.

QMutexLocker is a convenience for managing a QMutex using the RAII (http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization) paradigm. The QMutexLocker constructor is not atomic, but it will block at the point where it tries to lock the associated QMutex if another thread has already locked the QMutex, because the call to QMutex::lock within the QMutexLocker constructor will block and wait until the lock has been released.