So here's one approach I'm thinking about for implementing readers-writer synchronization. Does this seem reasonable as a starting point, or am I missing something much simpler?
I know there are various things you can prioritize for (readers vs. writers, etc), but I'm less concerned about those for now. The global state is-- * reader_count: an integer count of the active (reading) readers * writer_lock: an asyncio Lock object * no_readers_event: an asyncio Event object signaling no active readers * no_writer_event: an asyncio Event object signaling no active writer Untested pseudo-code for a writer-- async with writer_lock: no_writer_event.clear() # Wait for the readers to finish. await no_readers_event.wait() # Do the write. await write() # Awaken waiting readers. no_writer_event.set() Untested pseudo-code for a reader-- while True: await no_writer_event.wait() # Check the writer_lock again in case a new writer has # started writing. if not writer_lock.locked(): # Then we can do the read. break reader_count += 1 if reader_count == 1: no_readers_event.clear() # Do the read. await read() reader_count -= 1 if reader_count == 0: # Awaken any waiting writer. no_readers_event.set() One thing I'm not clear about is when the writer_lock is released and the no_writer_event set, are there any guarantees about what coroutine will be awakened first -- a writer waiting on the lock or the readers waiting on the no_writer_event? Similarly, is there a way to avoid having to have readers check the writer_lock again when a reader waiting on no_writer_event is awakened? --Chris On Sun, Jun 25, 2017 at 3:27 PM, Chris Jerdonek <chris.jerdo...@gmail.com> wrote: > On Sun, Jun 25, 2017 at 3:09 PM, Nathaniel Smith <n...@pobox.com> wrote: >> On Sun, Jun 25, 2017 at 2:13 PM, Chris Jerdonek >> <chris.jerdo...@gmail.com> wrote: >>> I'm using asyncio, and the synchronization primitives that asyncio >>> exposes are relatively simple [1]. Have options for async read-write >>> synchronization already been discussed in any detail? >> >> As a general comment: I used to think rwlocks were a simple extension >> to regular locks, but it turns out there's actually this huge increase >> in design complexity. Do you want your lock to be read-biased, >> write-biased, task-fair, phase-fair? Can you acquire a write lock if >> you already hold one (i.e., are write locks reentrant)? What about >> acquiring a read lock if you already hold the write lock? Can you >> atomically upgrade/downgrade a lock? This makes it much harder to come >> up with a one-size-fits-all design suitable for adding to something >> like the python stdlib. > > I agree. And my point about asyncio's primitives wasn't a criticism or > request that more be added. I was asking more if there has been any > discussion of general approaches and patterns that take advantage of > the event loop's single thread, etc. > > Maybe what I'll do is briefly write up the approach I have in mind, > and people can let me know if I'm on the right track. :) > > --Chris _______________________________________________ Async-sig mailing list Async-sig@python.org https://mail.python.org/mailman/listinfo/async-sig Code of Conduct: https://www.python.org/psf/codeofconduct/