[Async-sig] "read-write" synchronization

Nathaniel Smith njs at pobox.com
Tue Jun 27 18:52:48 EDT 2017


On Mon, Jun 26, 2017 at 6:41 PM, Chris Jerdonek
<chris.jerdonek at gmail.com> wrote:
> On Mon, Jun 26, 2017 at 12:37 PM, Dima Tisnek <dimaqq at 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


More information about the Async-sig mailing list