Skip to main content

GIL-powered* locking library for Python

Project description

aiologic is an async-aware library for synchronization and communication between tasks in different threads and different event loops. Just look at this example:

import time

from threading import Thread, get_ident

import anyio

from aiologic import Lock

lock = Lock()
start = time.monotonic()


async def func():
    print(
        f"{time.monotonic() - start:.0f}:",
        f"thread={get_ident()}",
        f"task={anyio.get_current_task().id}",
        'start',
    )

    async with lock:
        await anyio.sleep(1)

    print(
        f"{time.monotonic() - start:.0f}:",
        f"thread={get_ident()}",
        f"task={anyio.get_current_task().id}",
        'stop',
    )


async def main():
    async with anyio.create_task_group() as tasks:
        for _ in range(2):
            tasks.start_soon(func)


for _ in range(2):
    Thread(target=anyio.run, args=[main]).start()

It prints something like this:

0: thread=140011620005632 task=140011624407888 start
0: thread=140011611612928 task=140011602572720 start
0: thread=140011620005632 task=140011624408560 start
0: thread=140011611612928 task=140011602574512 start
1: thread=140011620005632 task=140011624407888 stop
2: thread=140011611612928 task=140011602572720 stop
3: thread=140011620005632 task=140011624408560 stop
4: thread=140011611612928 task=140011602574512 stop

As you can see, when using aiologic.Lock, tasks from different event loops have an equal opportunity to acquire a lock. Using anyio.Lock would raise a RuntimeError. And using threading.Lock would cause a deadlock.

Features

  • Python 3.8+ support

  • CPython and PyPy support

  • Cancellation and timeouts support

  • Optional Trio-style checkpoints

  • Only one checkpoint per asynchronous call

  • Fairness wherever possible (with some caveats)

  • Thread safety wherever possible

Synchronization primitives:

  • Semaphores: counting and bounded

  • Locks: primitive and reentrant

  • Conditions

  • Events: one-time and reusable

  • Resource guards

  • Queues: simple only

Supported concurrency libraries:

All synchronization primitives are implemented entirely on effectively atomic operations, which gives incredible speedup on PyPy compared to alternatives from the threading module. All this works thanks to GIL, but per-object locks also ensure that the same operations are still atomic, so aiologic also works when running in free-threaded mode.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aiologic-0.2.0.tar.gz (24.6 kB view hashes)

Uploaded Source

Built Distribution

aiologic-0.2.0-py3-none-any.whl (31.8 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page