-
-
Notifications
You must be signed in to change notification settings - Fork 345
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide Read-Write lock ? #528
Comments
It sounds tricky to guarantee some kind of fairness here. Would you mind me asking about your use case? In many cases atomicity of writes (e.g. on some complex data structure) can be enforced by not having any checkpoint within the write operation (so no task can start reading while we are writing). The point of a read-write lock is to increase concurrency of read operations, but in a cooperative concurrent model this could be translated in different ways depending on the use case. I tried to implement a variant of the lock without hacks. It uses the (You can also play with using two different parking lots for the readers and the writers, and wake them according with some specific policy, or use @attr.s()
class RWLock2:
_lot = attr.ib(default=attr.Factory(trio.hazmat.ParkingLot))
_read_lock_taken = attr.ib(default=0)
_global_lock_taken = attr.ib(default=False)
@asynccontextmanager
async def acquire_read(self):
while self._global_lock_taken:
await self._lot.park()
self._read_lock_taken += 1
yield
self._read_lock_taken -= 1
if not self._read_lock_taken:
self._lot.unpark()
await trio.sleep(0)
@asynccontextmanager
async def acquire_write(self):
while self._global_lock_taken or self._read_lock_taken:
await self._lot.park()
self._global_lock_taken = True
yield
self._global_lock_taken = False
self._lot.unpark()
await trio.sleep(0) |
@sorcio thanks a lot for you non-hacky rwlock implementation ;-)
Have a look here https://github.com/Scille/parsec-cloud/blob/54c34a3cdf69e4735e681a4ecf6c767eef57a0df/parsec/core/fs/folder.py#L193 I use rw-lock here to lock a single file/folder given working on it can mean accessing to remote data.
Since the post of this issue, I've rewritten my code following this idea to get rid of the rwlocks. The idea was to make copy of data before doing any await and rely on merge algorithm (see https://github.com/Scille/parsec-cloud/blob/8ec6d260852971e8379d230f4614a3b5f2b08bc6/parsec/core/fs2/__init__.py#L449).
In the end I'm a bit puzzled by this rwlock thing. |
Related to #19
I've implemented a reader-writer lock (following https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock#Implementation) for my own needs.
The codebase is really straightforward, except for the fact the
g
lock is released from a different coroutine that it was acquired in the first place. This obliged me to hack theg._owner
field...This make me wonder if it wouldn't be better to have this kind part of trio directly (given no normal user should be expected to use this kind of hack on a 3rd party dependency). Beside it's a fairly common kind of lock so DRY should apply here.
The text was updated successfully, but these errors were encountered: