Asynchronous Programming in Python

Jino Rohit
3 min readAug 18, 2023

--

Understanding synchronous and asynchronous programming in python

Let’s first start with understanding the difference between synchronous and asynchronous programming.

Synchronous programing is where you write your code and the execution happens in a sequential manner. This mean your first operation has to terminate for the next operation to happen. This can mean few things -

  1. If an operation takes a long time to execute, the operations are blocked. It exhibits a blocking behavior
  2. Point 1 in return leads to resource waiting and in turn makes the whole execution slower .

In turn , asynchronous programming allows tasks to overlap and run concurrently but not in parallel.

It is important to understand the difference between concurrency and parallelism before we go forward.

Parallelism is where multiple jobs or tasks or operations are running at the same time using multiple processors. Think of a restaurant with 10 chefs. A customer orders for 10 different food items. Now we can assign each chef to cook each food item. This is parallelism.

On the other hand, concurrency is where you also have multiple tasks running simultaneously but on a single processor. This means when an operation is taking too long, you switch control to the next available operation and start executing it. This mean there is no waiting for resources and all the operations are handled together. Considering the same example, only this time our chef has to cook an egg and chicken. The chef doesnot have to completely finish cooking the chicken to boil the egg. He can leave the chicken on the stove for 15 minutes and during that, he can get starting with boiling the egg :)

Credit : Getty Images

Now lets start with learning the foundations of async programming in python.

  1. Coroutines- These are specialized versions of functions. What makes them special is their ability to stop the execution of an operation midway and pass the control to another corountine for the next operation to take place. Just add the keyword async before your function definition.
async def my_coroutine():
print("Start")
await asyncio.sleep(1)
print("End")

2. Tasks- A unit of work that can be executed concurrently along with other tasks. It is created from a coroutine.

async def my_coroutine():
print("Start")
await asyncio.sleep(1)
print("End")

task = asyncio.create_task(my_coroutine())

3. Event loops- Tasks are managed by an event loop, which is responsible for scheduling and executing them. The event loop handles the execution of tasks, switching between them as they await asynchronous operations, such as I/O or timeouts.

loop = asyncio.new_event_loop()

That being said, let’s have a look at a full fledged code that downloads resources from a website that has a delay of 2 seconds . Let’s implement this using async programming in python. Make sure your python version is atleast 3.7 and above.

import asyncio

async def download_page(url):
print(f"Downloading {url}")
await asyncio.sleep(0.2) # Simulate a download delay
print(f"Downloaded {url}")

async def main():
urls = ["lol.com", "sike.org"]

# Create tasks for downloading each page concurrently
tasks = [asyncio.create_task(download_page(url)) for url in urls]

# Wait for all tasks to complete
await asyncio.gather(*tasks)

if __name__ == "__main__":
asyncio.run(main())


Output
##############################################################
Downloading lol.com
Downloading sike.org
Downloaded lol.com
Downloaded sike.org
[Finished in 454ms]

Do the outputs line up with what you were thinking? If not, don’t worry, let’s go through the flow step by step .

  1. The entry point to the program happens when the corountine main is called.
  2. A task is created for each coroutine and then awaited for for task execution to be completed.
  3. The main download page function is where the magic happens. First the url ‘lol.com’ is passed and printed, and on encountering the sleep, it realizes the execution needs to be paused and immediately gives control for the next task holding the url ‘sike.org’ . This again encounters the sleep, and now realizes the previous task has finished its sleep and hands the control back over. This process continues till the execution of each tasks gets completed.

Yaay! You just understood the basic elements of async programming. Now to scale onto more bigger and cooler stuffs , here are some resources.

  1. https://docs.python.org/3/library/asyncio.html
  2. https://realpython.com/async-io-python/

--

--

Jino Rohit
Jino Rohit

Written by Jino Rohit

Neurons that fire together, wire together

No responses yet