Source code for rwlock.imp_0.imp
"""
Module **rwlock.imp_0.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_0.imp``".
Or instantiate ``Imp`` in your own program and drive it from there.
"""
from threading import Lock, Condition
[docs]class Imp:
"""
An implementation of the read-write-lock service except that ``acqw()``
can starve if there is a continuous stream of ``acqr(); relr()``s.
It has four functions: ``acqr()``, ``relr()``, ``acqw()`` and ``relw()``.
It maintains the following variables:
- ``nr`` (int): number of threads holding a read lock; initially 0.
- ``nw`` (int): number of threads holding a write lock; initially 0.
- ``lck`` (lock): protects ``nr`` and ``nw``.
- ``cvr`` (condition): to wait for ``nw`` equal to 0.
- ``cvw`` (condition): to wait for ``nr`` and ``nw`` equal to 0.
When a thread executes ``acqw()``, it waits on ``cvw`` until ``nr``
and ``nw`` are 0, then increments ``nw`` and returns.
At this point, no thread can acquire a write lock or a read lock.
When a thread executes ``relw()``, it decrements ``nw`` and returns.
When a thread executes ``acqr()``, it waits on ``cvr`` until ``nw``
is 0, then increments ``nr`` and returns.
At this point a thread can get a read lock but not a write lock.
When a thread executes ``relr()``, it decrements ``nr`` and returns.
"""
def __init__(self):
self.nr = 0
self.nw = 0
self.lck = Lock()
self.cvr = Condition(self.lck)
self.cvw = Condition(self.lck)
def acqr(self):
with self.cvr:
while self.nw > 0:
self.cvr.wait()
self.nr += 1
def relr(self):
with self.lck:
self.nr -= 1
self.cvw.notify()
def acqw(self):
with self.cvw:
while self.nr + self.nw > 0:
self.cvw.wait()
self.nw += 1
def relw(self):
with self.lck:
self.nw -= 1
self.cvr.notify_all()
self.cvw.notify()
##### end class Imp #############################
if __name__ == '__main__':
imp = Imp()