Locks within the asyncio module are almost identical in terms of practical functionality when compared with the standard lock implementation you'll find living within the threading module.
The asyncio module implementation allows us to put locks around critical sections of our asyncio-based programs in order to ensure that no other coroutines are executing that same critical section simultaneously.
In order to instantiate a lock from the asyncio module, we have to do something like this:
Import asyncio
myLock = asyncio.Lock()
Let's take a look at a fully fledged example of this. We'll begin by defining an async coroutine called myWorker, which will take in our lock as our parameter. Within this myWorker coroutine, we will attempt to acquire the lock using the with keyword. Once we've attained this lock, we then execute our critical status, which in this instance happens to be a simple print statement.
Within our main coroutine, we then instantiate the lock that we'll be passing to our coroutine function. We then await the execution of two instances of our myWorker coroutine before completing:
import asyncio
import time
async def myWorker(lock):
with await lock:
print(lock)
print("myWorker has attained lock, modifying variable")
time.sleep(2)
print(lock)
print("myWorker has release the lock")
async def main(loop):
lock = asyncio.Lock()
await asyncio.wait([myWorker(lock),
myWorker(lock)])
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(main(loop))
finally:
loop.close()
If we were to execute this program, you should see that each worker, in turn, acquires the lock and performs what it has to perform before releasing the said lock and effectively allowing our second coroutine to take it up and execute its own critical section of code:
$ python3.6 asyncioLock.py
<asyncio.locks.Lock object at 0x103121dd8 [locked]>
myWorker has attained lock, modifying variable
<asyncio.locks.Lock object at 0x103121dd8 [unlocked]>
myWorker has release the lock
<asyncio.locks.Lock object at 0x103121dd8 [locked]>
myWorker has attained lock, modifying variable
<asyncio.locks.Lock object at 0x103121dd8 [unlocked]>
myWorker has release the lock