An old man in the sea.
An old man in the sea.

Reputation: 1508

What is the point for asyncio synchronization primitives not to be thread safe?

It seems that several asyncio functions, like those showed here, for synchronization primitives are not thread safe... By being not thread safe, considering for example asyncio.Lock, I assume that this lock won't lock the global variable, when we're running multiple threads in our computer, so race conditions are problem.

So, what's the point of having this Lock that doesn't lock? (not a criticism, but an honest doubt)

What are the case uses for these unsafe primitives?

Upvotes: 8

Views: 1909

Answers (1)

Ahmed AEK
Ahmed AEK

Reputation: 17526

For use-cases, look at what's Python asyncio.Lock() for?

As for why it is not thread-safe. It is mostly performance. Asyncio is not made for multithreaded work like old servers used to do, the asyncio eventloop itself is not thread-safe and only runs coroutines in a single thread, hence a lock that is only running in a single thread doesn't need to be threadsafe, and doesn't need to suffer from the extra overhead from using a thread-safe primitives.

Interacting with asyncio.lock suspends the current coroutine and instructs the eventloop to resume another coroutine (remember the eventloop is not thread-safe), those primitives don't need interaction with the OS unlike thead-safe ones which need to interact with the OS, which is the entire reason why asyncio is faster than old multithreaded servers.


You can use loop.run_in_executor to do tasks in another thread, those tasks can hold a threading.Lock while doing their work. This is preferred over trying to acquire the lock in the asyncio eventloop thread.

To use a threading.Lock in an async function you could wait for it indirectly using the answer in this question How to use threading.Lock in async function while object can be accessed from multiple thread as commented by @dano.


It is not that those primitives can't be made threadsafe. They can be made to work similar to loop.call_soon_threadsafe or the above method which is more expensive than a normal threading.lock. Thread-safe locks are expensive and thread-safe interactions with the eventloops are even more expensive, because you need to send a message to the eventloop to interact with it.

Upvotes: 7

Related Questions