{"id":2375,"library":"aiorwlock","title":"aiorwlock: Read Write Lock for Asyncio","description":"aiorwlock provides a read-write lock, a synchronization primitive for `asyncio` applications. It allows multiple reader tasks to hold a lock concurrently, while a writer task obtains an exclusive lock, blocking all readers and other writers. This pattern is ideal for resources that are frequently read but infrequently written. The library is currently at version 1.5.1 and maintains an active release cadence with several minor and patch updates per year.","status":"active","version":"1.5.1","language":"python","source_language":"en","source_url":"https://github.com/aio-libs/aiorwlock","tags":["asyncio","lock","read-write lock","synchronization","concurrency"],"install":[{"cmd":"pip install aiorwlock","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Required runtime environment.","package":"python","optional":false}],"imports":[{"symbol":"RWLock","correct":"from aiorwlock import RWLock"}],"quickstart":{"code":"import asyncio\nfrom aiorwlock import RWLock\n\nasync def reader_task(rwlock: RWLock, reader_id: int):\n    print(f\"Reader {reader_id}: Attempting to acquire read lock\")\n    async with rwlock.reader_lock:\n        print(f\"Reader {reader_id}: Acquired read lock\")\n        await asyncio.sleep(0.05) # Simulate reading\n        print(f\"Reader {reader_id}: Released read lock\")\n\nasync def writer_task(rwlock: RWLock, writer_id: int):\n    print(f\"Writer {writer_id}: Attempting to acquire write lock\")\n    async with rwlock.writer_lock:\n        print(f\"Writer {writer_id}: Acquired write lock\")\n        await asyncio.sleep(0.1) # Simulate writing\n        print(f\"Writer {writer_id}: Released write lock\")\n\nasync def main():\n    rwlock = RWLock()\n    tasks = []\n    # Start some readers\n    for i in range(3):\n        tasks.append(asyncio.create_task(reader_task(rwlock, i)))\n    # Start a writer in between\n    tasks.append(asyncio.create_task(writer_task(rwlock, 100)))\n    # Start more readers\n    for i in range(3, 6):\n        tasks.append(asyncio.create_task(reader_task(rwlock, i)))\n\n    await asyncio.gather(*tasks)\n\nif __name__ == \"__main__\":\n    asyncio.run(main())","lang":"python","description":"This example demonstrates basic usage of `RWLock` with multiple concurrent readers and a single writer. Readers can acquire the `reader_lock` simultaneously, but a writer acquiring the `writer_lock` will block all other readers and writers."},"warnings":[{"fix":"Upgrade Python to 3.8 or newer. The current minimum supported version is Python 3.9.","message":"Python 3.7 support was dropped in v1.4.0. Users on Python 3.7 or older must upgrade their Python version to use `aiorwlock` v1.4.0 or newer.","severity":"breaking","affected_versions":">=1.4.0"},{"fix":"Remove the `loop` argument from `RWLock()` constructor calls. `aiorwlock` now lazily evaluates the current event loop.","message":"The explicit `loop` parameter for the `RWLock` constructor was deprecated in v1.0.0 and removed in v1.3.0. Passing a `loop` argument will now raise an error.","severity":"breaking","affected_versions":">=1.3.0"},{"fix":"Ensure `RWLock()` instances are created within an `async` function or a context where `asyncio.get_running_loop()` can correctly resolve the event loop.","message":"Creation of `RWLock` instances outside of an `async` function context was deprecated in v1.0.0. While it might still work in some setups due to lazy loop evaluation, it's considered bad practice.","severity":"deprecated","affected_versions":">=1.0.0"},{"fix":"Upgrade to `aiorwlock` v1.5.1 or newer to benefit from critical stability fixes.","message":"Fixed a cross-event-loop race condition in lock acquisition and a deadlock that could occur when tasks are cancelled.","severity":"gotcha","affected_versions":"<1.5.1"},{"fix":"Upgrade to `aiorwlock` v1.2.0 or newer to ensure correct exclusive write lock behavior.","message":"Fixed a bug that allowed concurrent writes under rare conditions.","severity":"gotcha","affected_versions":"<1.2.0"},{"fix":"Always ensure that the same `async` task (coroutine) that acquires a `reader_lock` or `writer_lock` is also responsible for releasing it (e.g., by using `async with`).","message":"A `RuntimeError` will be raised if a lock is acquired by one task but released by another. Synchronization primitives in `asyncio` are typically task-bound.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-20T21:40:55.006Z","next_check":"2026-07-09T00:00:00.000Z","problems":[{"fix":"pip install aiorwlock","cause":"The 'aiorwlock' module is not installed in the Python environment.","error":"ModuleNotFoundError: No module named 'aiorwlock'"},{"fix":"from aiorwlock import RWLock","cause":"The 'RWLock' class is not found in the 'aiorwlock' module, possibly due to an incorrect import statement.","error":"AttributeError: module 'aiorwlock' has no attribute 'RWLock'"},{"fix":"Ensure that the 'RWLock' instance is used within the same asyncio event loop where it was created.","cause":"An attempt was made to use 'aiorwlock' across different asyncio event loops, which is not supported.","error":"RuntimeError: Task got Future <Future pending> attached to a different loop"},{"fix":"Ensure that the `RWLock`'s reader or writer lock is acquired and released within the same asyncio task, typically by using `async with` statements or by calling `acquire()` and `release()` from the same coroutine.","cause":"The read-write lock was acquired by one asyncio task but attempted to be released by a different task, which is not permitted by `aiorwlock`'s design.","error":"RuntimeError: A task that acquires the lock should be used for releasing it."},{"fix":"Prepend `await` when calling `acquire()` or use `async with` when entering the reader/writer lock context. For example, `async with rwlock.reader_lock:` or `await rwlock.reader_lock.acquire()`.","cause":"You are calling an asynchronous method or accessing an awaitable context manager (like `rwlock.reader_lock` or `rwlock.writer_lock`) but are not using the `await` keyword or `async with` statement to schedule or enter it.","error":"RuntimeWarning: coroutine 'RWLock.reader_lock' was never awaited"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.5.1","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/aio-libs/aiorwlock","docs":"https://github.com/aio-libs/aiorwlock","changelog":null,"pypi":"https://pypi.org/project/aiorwlock/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["http-networking","workflow"],"base_url":null,"auth_type":null,"install_checks":{"last_tested":"2026-05-20","tag":null,"tag_description":null,"installed_version":"1.5.1","pypi_latest":"1.5.1","is_stale":false,"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"aiorwlock","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.08,"mem_mb":4,"disk_size":"17.8M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"aiorwlock","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.12,"mem_mb":4,"disk_size":"17.8M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"aiorwlock","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.4,"import_time_s":0.06,"mem_mb":4,"disk_size":"18M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"aiorwlock","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":4,"disk_size":"18M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"aiorwlock","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.15,"mem_mb":4.9,"disk_size":"19.6M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"aiorwlock","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.21,"mem_mb":4.9,"disk_size":"19.6M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"aiorwlock","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.6,"import_time_s":0.14,"mem_mb":4.9,"disk_size":"20M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"aiorwlock","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.18,"mem_mb":4.9,"disk_size":"20M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"aiorwlock","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.34,"mem_mb":8.2,"disk_size":"11.5M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"aiorwlock","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.64,"mem_mb":8.2,"disk_size":"11.5M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"aiorwlock","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.4,"import_time_s":0.32,"mem_mb":8.2,"disk_size":"12M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"aiorwlock","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.45,"mem_mb":8.2,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"aiorwlock","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.36,"mem_mb":8.7,"disk_size":"11.3M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"aiorwlock","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.57,"mem_mb":8.7,"disk_size":"11.2M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"aiorwlock","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.4,"import_time_s":0.32,"mem_mb":8.7,"disk_size":"12M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"aiorwlock","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.6,"mem_mb":8.7,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"aiorwlock","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.07,"mem_mb":3.9,"disk_size":"17.3M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"aiorwlock","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.12,"mem_mb":3.9,"disk_size":"17.3M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"aiorwlock","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.7,"import_time_s":0.07,"mem_mb":3.9,"disk_size":"18M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"aiorwlock","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.11,"mem_mb":3.9,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-25","tag":null,"tag_description":null,"results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]},"_links":{"self":"https://checklist.day/api/registry/aiorwlock","v1":"https://checklist.day/v1/registry/aiorwlock","v1_install":"https://checklist.day/v1/registry/aiorwlock/install","v1_imports":"https://checklist.day/v1/registry/aiorwlock/imports","v1_compatibility":"https://checklist.day/v1/registry/aiorwlock/compatibility","v1_quickstart":"https://checklist.day/v1/registry/aiorwlock/quickstart","docs":"https://checklist.day/docs"}}