Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from contextlib import contextmanager
- from threading import Condition, Thread, Lock
- import time
- class SharedLock:
- def __init__(self):
- self._lock = Lock()
- self._readcond = Condition(self._lock)
- self._writecond = Condition(self._lock)
- self._readers = 0
- self._writers_waiting = 0
- @contextmanager
- def __call__(self, lock_type: str):
- if lock_type == 'shared':
- with self._lock:
- while self._writers_waiting:
- self._readcond.wait()
- self._readers += 1
- yield self
- with self._lock:
- self._readers -= 1
- if not self._readers:
- self._writecond.notify()
- elif lock_type == 'exclusive':
- with self._lock:
- self._writers_waiting += 1
- while self._readers:
- self._writecond.wait()
- self._writers_waiting -= 1
- yield self
- if self._writers_waiting:
- self._writecond.notify()
- else:
- self._readcond.notify_all()
- else:
- raise ValueError(f'Invalid lock_type {lock_type!r}')
- if __name__ == '__main__':
- shared_lock = SharedLock()
- def reader():
- with shared_lock('shared'):
- print('start reading', time.time())
- time.sleep(1)
- print('end reading', time.time())
- # Give writer thread a chance to acquire exclusive use:
- #time.sleep(.1)
- #with shared_lock('shared'):
- # print('start reading', time.time())
- # time.sleep(1)
- # print('end reading', time.time())
- def writer():
- # Give reader threads a chance to acquire shared use:
- time.sleep(.1)
- with shared_lock('exclusive'):
- print('start writing', time.time())
- time.sleep(1)
- print('end writing', time.time())
- def test():
- reader_threads = [
- Thread(target=reader) for _ in range(1)
- ]
- writer_threads = [
- Thread(target=writer) for _ in range(2)
- ]
- for t in reader_threads:
- t.start()
- for t in writer_threads:
- t.start()
- for t in reader_threads:
- t.join()
- for t in writer_threads:
- t.join()
- test()
Advertisement