Reader-Writer Lock
The `readerwriterlock` library provides a Python 3 implementation of the three classic Reader-Writer problems. It offers different lock types (Reader priority, Writer priority, Fair priority) and is compliant with the standard Python lock interface, including support for timeouts. The current version is 1.0.9, and releases are infrequent, indicating a stable and mature library.
Warnings
- gotcha Versions prior to 1.0.9, when used with Python 3.9.7, could encounter a `TypeError: Protocols cannot be instantiated` due to an incompatibility with `typing.Protocol`.
- gotcha The downgradable lock classes (`RWLockReadD`, `RWLockWriteD`, `RWLockFairD`) introduce a theoretical ~20% performance overhead for acquiring and releasing locks compared to their non-downgradable counterparts.
- gotcha This library implements reader-writer locks for *threads* within a single process. It does not support inter-process communication or distributed locking.
- gotcha Python 3.13+ is planned to include a built-in `threading.RWLock`. Users on newer Python versions may consider using the standard library implementation over this third-party library.
Install
-
pip install readerwriterlock
Imports
- RWLockRead, RWLockWrite, RWLockFair
from readerwriterlock import rwlock lock = rwlock.RWLockFair()
- RWLockReadD, RWLockWriteD, RWLockFairD
from readerwriterlock import rwlock lock = rwlock.RWLockFairD()
Quickstart
from readerwriterlock import rwlock
import threading
import time
# Choose a fair, downgradable lock for a balanced approach
lock = rwlock.RWLockFairD()
shared_resource = []
def reader(reader_id):
with lock.gen_rlock():
# Multiple readers can enter this block concurrently
print(f"Reader {reader_id}: Reading {shared_resource}")
time.sleep(0.1) # Simulate read operation
def writer(writer_id):
with lock.gen_wlock():
# Only one writer can enter this block
old_val = list(shared_resource)
shared_resource.append(writer_id)
print(f"Writer {writer_id}: Wrote {writer_id}, was {old_val}, now {shared_resource}")
time.sleep(0.2) # Simulate write operation
threads = []
for i in range(3):
threads.append(threading.Thread(target=reader, args=(f'R{i}',)))
threads.append(threading.Thread(target=writer, args=(f'W{i}',)))
for t in threads:
t.start()
for t in threads:
t.join()
print(f"Final resource state: {shared_resource}")