Anatomy of a Monitor
A monitor is a class in some languages, designed to protect its variables from interference when its methods are called by different threads running in parallel. The variables of a monitor take on values which are inter-dependent, so that a modification to one requires that others also change, in a synchronized fashion. Within a monitor, any data structure can be used with no fear of trouble due to interference between threads.
C++ does not directly implement a monitor class. However, by adding some synchronization to an existing class, the essential feature (protection from other parallel threads) can be achieved. To provide this protection, a single Lock is added to the existing class. This Lock is usually Acquire()d at entrance to each method, and not Release()d until the method exits. This forces all the methods to run in mutual exclusion.
Methods must sometimes Wait(), and/or Signal() other methods to wake up from a Wait(). Condition Variables are provided to allow this, with each CV associated with a logical test of shared variables which indicates that the testing thread should Wait(), or should Signal(). Both Wait() and Signal() should be issued while the Lock is held, since otherwise, another thread could be switched to after the test, but before the Signal() or Wait(), and the new thread could change the tested variables, before switching back.
Note that when more than one thread is ready to run, the scheduler, which is NOT under control of any thread, chooses which of the ready threads to run next. Thus, if a Signal() wakes up more than one thread, all the newly awakened threads, along with the thread doing the Signal() all become candidates for next-to-run. Wait() can PREVENT the issuing thread from running, until that thread is awakened; Signal() can awaken a single thread, but CANNOT ensure that the newly awakened thread is switched to immediately. In a monitor, typically new requests to enter the monitor compete for the CPU, along with the newly awakened thread. The variables of the monitor which indicate the monitor’s “state” must be tested to cause any unwanted threads to Wait(). This test must be repeated when the Wait() returns, because some other thread may have seized the Lock(), run, and changed the “state” variables after the Signal() was issued, and before the waiting thread has a chance to run.
Safe rules for coding monitors