On Sat, Apr 18, 2020 at 11:16 AM Antoine Pitrou <solipsis@pitrou.net> wrote:
* I do think a minimal synchronization primitive would be nice. Either a Lock (in the Python sense) or a Semaphore: both should be relatively easy to provide, by wrapping an OS-level synchronization primitive. Then you can recreate all high-level synchronization primitives, like the threading and multiprocessing modules do (using a Lock or a Semaphore, respectively).
(note you should be able to emulate a semaphore using blocking send() and recv() calls, but that's probably not very efficient, and efficiency is important)
You make a good point about efficiency. The blocking is definitely why I figured we could get away with avoiding a locking primitive. One reason I wanted to avoid a shareable synchronization primitive is that I've had many bad experiences with something similar in Go: mixing locks, channels, and goroutines). I'll also admit that the ideas in CSP had an impact on this. :) Mixing channels and locks can be a serious pain point. So if we do end up supporting shared locks, I suppose I'd feel better about it if we had an effective way to discourage folks using them normally. Two possible approaches: * keep them in a separate module on PyPI that folks could use when experimenting * add a shareable lock class (to the "interpreters" module) with a name that made it clear you shouldn't use it normally. If blocking send/recv were efficient enough, I'd rather not have a shareable lock at all. Or I suppose it could be re-implemented later using a channel. :) On Sat, Apr 18, 2020 at 11:30 AM Antoine Pitrou <solipsis@pitrou.net> wrote:
By the way, perhaps this could be even be implemented as making _threading.Lock shareable. This would probably require some changes in the underlying C Lock structure (e.g. pointing to an atomically-refcounted shared control block), but nothing intractable, and reasonably efficient.
Making _threading.Lock shareable kind of seems like the best way to go. Honestly I was already looking into it relative to the implementation for the low-level channel_send_wait(). [1] However, I got nervous about that as soon as I started looking at how to separate the low-level mutex from the Lock object (so it could be shared). :) So I'd probably want some help on the implementation work. -eric [1] https://www.python.org/dev/peps/pep-0554/#return-a-lock-from-send