Author Sebastian.Noack
Recipients Sebastian.Noack, asvetlov, jyasskin, kristjan.jonsson, mklauber, pitrou
Date 2012-09-29.12:38:57
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1348922338.55.0.379890802813.issue8800@psf.upfronthosting.co.za>
In-reply-to
Content
I would love to see a reader/writer lock implementation shipped with Python's threading (and multiprocessing) module. But I have some issues with the patch:

1. I would avoid the terms 'read' and 'write' as those terms are referring just to one of many use cases. A better and more generic name would be shared and exclusive lock.

2. If we add a new synchronization primitive to the threading module we really should add it also to the multiprocessing module, for consistency and to keep switching between threading and multiprocessing as easy as it is right now.

3. The methods rdlock() and wrlock() might even block if you call them with blocking=False. That's because of they acquire the internal lock in a blocking fashion before they would return False.

4. As Antoine already pointed out, it is a bad idea to make acquiring the exclusive (write) lock, the default behavior. That clearly violates the Zen of Python, since explicit is better than implicit.

5. The issue above only raises from the idea that the RWLock should provide the same API as the Lock and RLock primitives. So everywhere where a lock primitive is expected, you can pass either a Lock, RLock or RWLock. That is actually a good idea, but in that case you should explicitly specify, whether to pass the shared (read) or the exclusive (write) lock.

Both issues 4. and 5. only raise from the idea that a shared/exclusive lock should be implemented as a single class. But having two different lock primitives, one for the shared lock and one for the exclusive lock and a function returning a pair of those, would be much more flexible, pythonic and compatible with existing lock primitives.

def ShrdExclLock()
  class _ShrdLock(object):
    def acquire(self, blocking=True):
      ...

    def release(self, blocking=True):
      ...

    def __enter__(self):
      self.acquire()
      retrun self

    def __exit__(self, exc_value, exc_type, tb):
      self.release()

  class _ExclLock(object):
    def acquire(self, blocking=True):
      ...

    def release(self, blocking=True):
      ...

    def __enter__(self):
      self.acquire()
      retrun self

    def __exit__(self, exc_value, exc_type, tb):
      self.release()

  return _ShrdLock(), _ExclLock()

# create a shared/exclusive lock
shrd_lock, excl_lock = ShrdExclLock()
History
Date User Action Args
2012-09-29 12:38:58Sebastian.Noacksetrecipients: + Sebastian.Noack, pitrou, kristjan.jonsson, jyasskin, asvetlov, mklauber
2012-09-29 12:38:58Sebastian.Noacksetmessageid: <1348922338.55.0.379890802813.issue8800@psf.upfronthosting.co.za>
2012-09-29 12:38:58Sebastian.Noacklinkissue8800 messages
2012-09-29 12:38:57Sebastian.Noackcreate