The Mutex object is probably the simplest and most useful of all synchronization objects. Most of the other objects can be implemented by solely using mutex objects. Its basic purpose is to provide safe manipulation of a block of data across threads. In this C++ implementation, we'll consider a class such as this:
class CMutex { public: void Lock(); // Lock the mutex before accessing the data. void Unlock(); // Unlock the mutex when done with the data. };
Such an object would be used, in the silly example proposed in Windows Synchronization Objects, in this manner:
Data:
int Var1; int Var1plus2; CMutex Var1Mutex;
Thread 1:
Var1Mutex.Lock(); Var1 = 5; Var1plus2 = 7; Var1Mutex.Unlock();
Thread 2:
Var1Mutex.Lock(); Var1 = 3; Var1plus2 = 5; Var1Mutex.Unlock();
Now, if Thread 1 is interrupted just after the Var1 = 5 line, and Thread 2 attempts to cross its Lock() call, Thread 2 will pause and stay frozen until Thread 1 calls its Unlock() call. Therefore, the data is never updated improperly.
In a more general way, the mutex object can be viewed as allowing only, at most, one thread to be within a fragment of the code that is enclosed between calls to the Lock() and Unlock() methods of the same mutex object. This raises a few questions:
The answer to questions 1 and 2 is, of course implementation-dependent. For our particular case, which is the implementation of all this in the Windows environment, we can extract some information from the Windows API and extrapolate. For the third question, the answer is that no other thread will be able to get past the Lock() call. If the thread that didn't call Unlock() attempts to enter another pair of Lock() and Unlock() calls for the same mutex object, then the behaviour depends on the answer to the second question.
First, we'll see a possible Windows implementation of the CMutex class. We'll call it CThreadMutex, for reasons that will become clear later:
class CMutex { private: CRITICAL_SECTION cs; // Windows' basic mutex object. public: void Lock() { EnterCriticalSection(&cs); } void Unlock() { LeaveCriticalSection(&cs); } CMutex() { InitializeCriticalSection(&cs); } ~CMutex() { DeleteCriticalSection(&cs); } };
Following the Windows API, we can see that the answers to the questions raised are:
All this brings us into the very first rule of multi-threaded programming:
All trademarked things I mention here are TM by their respective owners. If you are one of those owners and want to be specifically mentioned, please, contact me and I'll include it.
Go back to the main index of JCAB's Rumblings
Wow!
hits and increasing...
To contact JCAB: jcab@JCABs-Rumblings.com
Last updated: [an error occurred while processing this directive]