Reputation: 1508
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
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