![](https://secure.gravatar.com/avatar/97c543aca1ac7bbcfb5279d0300c8330.jpg?s=120&d=mm&r=g)
On Mon, Jun 26, 2017 at 6:41 PM, Chris Jerdonek <chris.jerdonek@gmail.com> wrote:
On Mon, Jun 26, 2017 at 12:37 PM, Dima Tisnek <dimaqq@gmail.com> wrote:
Chris, here's a simple RWLock implementation and analysis: ... Obv., this code could be nicer: * separate context managers for read and write cases * .unlock can be automatic (if self.writer: unlock_for_write()) at the cost of opening doors wide open to bugs * policy can be introduced if `.lock` identified itself (by an object(), since there's no thread id) in shared state * notifyAll() makes real life use O(N^2) for N being number of simultaneous write lock requests
Feel free to use it :)
Thanks, Dima. However, as I said in my earlier posts, I'm actually more interested in exploring approaches to synchronizing readers and writers in async code that don't require locking on reads. (This is also why I've always been saying RW "synchronization" instead of RW "locking.")
I'm interested in this because I think the single-threadedness of the event loop might be what makes this simplification possible over the traditional multi-threaded approach (along the lines Guido was mentioning). It also makes the "fast path" faster. Lastly, the API for the callers is just to call read() or write(), so there is no need for a general RWLock construct or to work through RWLock semantics of the sort Nathaniel mentioned.
I coded up a working version of the pseudo-code I included in an earlier email so people can see how it works. I included it at the bottom of this email and also in this gist: https://gist.github.com/cjerdonek/858e1467f768ee045849ea81ddb47901
FWIW, to me this just looks like an implementation of an async RWLock? It's common for async synchronization primitives to be simpler internally than threading primitives because the async ones don't need to worry about being pre-empted at arbitrary points, but from the caller's point of view you still have basically a blocking acquire() method, and then you do your stuff (potentially blocking while you're at it), and then you call a non-blocking release(), just like every other async lock. -n -- Nathaniel J. Smith -- https://vorpus.org