GIL-powered* locking library for Python
Project description
aiologic is an async-aware library for tasks synchronization and their communication in different threads and different event loops. Let’s take a look at the 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 are all able to acquire a lock. In the same case if you use anyio.Lock, it will raise a RuntimeError. And threading.Lock will cause a deadlock.
Features
Python 3.8+ 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 an incredible speedup on PyPy compared to alternatives from the threading module. All this works because of GIL, but per-object locks also ensure that the same operations are still atomic, so aiologic also works when running in a 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.