Skip to content

Running Tasks Concurrently with asyncio

Python's asyncio module enables you to run code concurrently, which is particularly useful for I/O-bound operations like reading from sensors, fetching data, or controlling devices. This approach allows multiple tasks to run without blocking each other, similar to executing multiple subroutines in parallel.

Key Concepts

  1. async Functions: Defined using async def, these functions can pause and resume their execution, allowing other tasks to run during the pause.
  2. await Keyword: Used within async functions to pause execution until the awaited task completes, during which other tasks can proceed.
  3. Event Loop: The core component that manages and schedules the execution of asynchronous tasks.

Example 1: Basic Asynchronous Task

Here's a simple example to demonstrate asynchronous execution:

import asyncio

async def say_hello():
    print("Hello!")
    await asyncio.sleep(1)  # Simulate a delay
    print("World!")

async def main():
    await asyncio.gather(say_hello(), say_hello())  # Run both tasks concurrently

asyncio.run(main())

Explanation

  • asyncio.sleep(1): Pauses the function for 1 second without blocking other tasks.
  • asyncio.gather(): Runs multiple asynchronous functions concurrently.

Example 2: Running Multiple I/O Operations

Let's simulate running several I/O tasks concurrently:

import asyncio

async def read_sensor(sensor_id):
    print(f"Reading sensor {sensor_id}...")
    await asyncio.sleep(2)  # Simulate sensor delay
    print(f"Sensor {sensor_id} data received!")

async def main():
    tasks = [read_sensor(i) for i in range(3)]
    await asyncio.gather(*tasks)  # Run all sensor reads concurrently

asyncio.run(main())

Explanation

  • Multiple read_sensor() calls: Simulates reading from three sensors concurrently.
  • await asyncio.gather(): Runs all sensor reads concurrently, reducing total execution time compared to sequential execution.

Summary

asyncio allows you to run coroutines (asynchronous functions) concurrently. The event loop manages the execution of these coroutines, allocating runtime during await periods.

Further reading