【Python】Basics of Implementing Asynchronous Processing with async/await

目次

Overview

This article explains the basic way to write “Asynchronous Processing” using Python’s asyncio module. Traditional synchronous processing (using time.sleep) stops the entire program until a task is finished. By using asynchronous processing (using await asyncio.sleep), you can efficiently handle other tasks while waiting for one to complete.

Specifications (Input/Output)

  • Input: Defining and calling an asynchronous function (coroutine).
  • Output: Results of tasks executed asynchronously.
  • Syntax:
    • async def: Defines an asynchronous function (coroutine).
    • await: Waits for the result of an asynchronous process (returns control to the loop until finished).
    • asyncio.run(): Starts execution as the entry point for asynchronous processing.

Basic Usage

Add async before your function definition and await before the processes that involve waiting. Use asyncio.run() to execute the function.

1. Synchronous Processing (Traditional Method)

The program blocks (stops) until the process is complete.

import time

def fetch_data_sync():
    print("Starting data fetch (Sync)...")
    time.sleep(3) # The program stops completely here
    print("Data fetch complete")
    return "Finished"

# Execution
print(fetch_data_sync())

2. Asynchronous Processing (async/await)

This is efficient because control returns to the event loop while waiting.

import asyncio

async def fetch_data_async():
    print("Starting data fetch (Async)...")
    await asyncio.sleep(3) # Non-blocking wait
    print("Data fetch complete")
    return "Finished"

# Execution
if __name__ == "__main__":
    result = asyncio.run(fetch_data_async())
    print(result)

Full Code

This is a complete sample code that defines an asynchronous function and calls it from a main function.

import asyncio
import time

# --- Defining an Asynchronous Function (async def) ---
async def fetch_data():
    """Coroutine simulating data retrieval"""
    print("[Task] Sending data fetch request...")
    
    # Asynchronous sleep (await asyncio.sleep)
    # Using time.sleep(3) here would block the whole program
    await asyncio.sleep(3)
    
    print("[Task] Data received")
    return "Sample Data"

# --- Defining the Main Coroutine ---
async def main():
    print("--- Process Started ---")
    
    # Wait for the coroutine to finish and receive the return value
    # The program waits for 3 seconds here, but it does not block the thread
    result = await fetch_data()
    
    print(f"Result: {result}")
    print("--- Process Finished ---")

# --- Execution ---
if __name__ == "__main__":
    # Start the event loop and run main() using asyncio.run()
    asyncio.run(main())

Customization Points

Summary of Syntax and Meanings

SyntaxMeaning / RoleNotes
async def func():Defines a coroutine function.Calling this returns a “coroutine object,” not the execution result.
awaitWaits for coroutine execution.It waits for the process to finish and receives the result. Can only be used inside async def.
asyncio.run(coro)Starts execution.Creates an event loop and runs the top-level coroutine. Call it once at the entry point.

Important Notes

Differences in Calling

Functions defined with async def will not run if you simply call them like func(). This only creates a “coroutine object.” You must execute them using await func() (inside an async function) or asyncio.run(func()) (at the entry point).

Avoid time.sleep

If you use time.sleep() inside an async def function, the benefits of asynchronous processing disappear, and the entire program will freeze. Always use await asyncio.sleep().

Running in Jupyter Notebook

Jupyter Notebook and Google Colab already have an event loop running. Using asyncio.run() will cause an error. In these environments, simply use await main() to execute.

Advanced Usage

This example uses asyncio.gather to execute multiple asynchronous tasks “concurrently” to reduce the total waiting time.

import asyncio

async def task(name, seconds):
    print(f"{name} started (Waiting {seconds}s)")
    await asyncio.sleep(seconds)
    print(f"{name} finished")
    return f"Result of {name}"

async def main():
    print("Starting concurrent execution")
    # Start two tasks (2s and 3s) at the same time
    # Total time will be the longer duration (3s), not the sum (5s)
    results = await asyncio.gather(
        task("Task-A", 2),
        task("Task-B", 3)
    )
    print(f"All results: {results}")

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

Summary

The basic set of asynchronous processing is defining with async def, waiting with await, and starting with asyncio.run(). Start by getting used to using await asyncio.sleep instead of time.sleep.

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次