Source code for rwlock.imp_2.imp

"""
Module **rwlock.imp_2.imp** has class ``Imp`` that implements
the read-write-lock service except that it allows writes to starve.
To instantiate and drive ``Imp`` from **rwlock/user.py**, in the parent
directory run "``python user.py <num_threads> <num_ops> imp_2.imp``".
Or instantiate ``Imp`` in your own program and drive it from there.

This implementation is of historical interest. It's one of the earliest
solutions and is the one typically presented in texts. It uses sempahores
in a "odd" way (locks and condition variables were not invented yet).
"""

from threading import Semaphore

[docs]class Imp: """ An implementation of the read-write-lock service except that it allows writers to starve if there is a continuous supply of readers. It has four functions: ``acqw()``, ``relr()``, ``acqw()`` and ``relw()``. It maintains the following variables: - ``nr`` (int): number of threads holding the read lock; initially 0. - ``nr_mutex`` (semaphore): protects nr; "count" initially 1. - ``rw_mutex`` (semaphore): protects a read or write interval; "count" initially 1. When ``rw_mutex`` is free (ie, its count is 1), no thread holds a read lock, no thread holds a write lock, and ``nr`` is 0. When a thread executes ``acqw()``, it acquires ``rw_mutex``. When it executes ``relw()``, it releases ``rw_mutex``. Until then, no other thread can acquire a write lock or a read lock (because ``rw_mutex`` is not free). When a thread executes ``acqr()``, if ``nr`` is 0 it acquires ``rw_mutex`` and increments ``nr``. At this point no thread can get a write lock. But another thread can get a read lock, because when it executes ``acqr()`` it would find ``nr > 0`` and so would not attempt to acquire ``rw_mutex)``. When a thread executes ``relr()``, it decrements ``nr`` and, if ``nr`` is 0 it releases ``rw_mutex``. """ def __init__(self): self.nr = 0 self.nr_mutex = Semaphore(1) self.rw_mutex = Semaphore(1) def acqr(self): self.nr_mutex.acquire() if self.nr == 0: self.rw_mutex.acquire() self.nr += 1 self.nr_mutex.release() def relr(self): self.nr_mutex.acquire() self.nr -= 1 if self.nr == 0: self.rw_mutex.release() self.nr_mutex.release() def acqw(self): self.rw_mutex.acquire() def relw(self): self.rw_mutex.release()
##### end class Imp ############################# if __name__ == '__main__': imp = Imp()