1

Let's imagine I have a thread with an asyncio event loop and other threads running.

I may have to deal with synchronisation between threads with the lock mecanism for instance. But the lock may block the coroutine... And no other tasks (in the asyncio thread) will run concurrently.

What is the solution ? My guess is that a kind of lock primitivve which would be asynchronous could do the job but it does not exist as far as I know.

To be precise: I do not refer to the existing asyncio lock primitive.

2
  • We surely need an example. Now it is not clear why are you mixing up threads and asyncio; And what are you going to lock Commented Apr 22, 2017 at 23:31
  • This question is similar to: Asyncio threadsafe primitives. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. Commented Nov 21, 2024 at 21:51

2 Answers 2

2

Use loop.run_in_executor to run a synchronous call in a thread:

def synchronous_function():
    with synchronous_lock:
        # Do something

async def asynchronous_function():
    await loop.run_in_executor(None, synchronous_function)
Sign up to request clarification or add additional context in comments.

Comments

0

Now an async-aware lock exists. You can use aiologic.BinarySemaphore as the fastest lock implementation provided by the corresponding package (I'm the creator of aiologic). It's similar to threading.Lock, and it never block the event loop:

import asyncio

from threading import Timer

import aiologic

lock = aiologic.BinarySemaphore()


async def a():
    print("before enter")

    async with lock:
        pass

    print("after exit")


async def b():
    print("another task")


async def main():
    async with asyncio.TaskGroup() as tasks:
        lock.green_acquire()

        tasks.create_task(a())
        tasks.create_task(b())

        Timer(1, lock.green_release).start()


asyncio.run(main())  # will take 1 second

But unlike threading.Lock, it omits checks for redundant release() calls. If you need them, you can use aiologic.Semaphore(max_value=1) instead.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.