Pythonのawaitによる非同期処理の制御と使い方をわかりやすく解説

スポンサーリンク
スポンサーリンク

awaitの概要

非同期処理の実行待機 Python予約語

await

概要 awaitはPythonで非同期処理を制御するために使われる予約語です。async関数内で使用され、非同期処理が完了するまで一時停止し、完了後に処理を再開します。

わかりやすく説明 awaitは「結果が出るまで待つ」という動作をします。非同期処理を中断し、結果が返ってきたら次の処理を実行します。

  • awaitasync関数内でのみ使用できます。
  • 非同期処理の実行を一時停止し、完了後に次の処理を再開します。
  • asyncioaiohttpなどの非同期ライブラリと組み合わせて使われます。

awaitの基本的な使い方

awaitを使うと、非同期処理の結果を待ってから次の処理を実行できます。

# awaitの基本的な使い方
import asyncio

async def example():
    print("処理開始")
    await asyncio.sleep(2)  # 2秒待機
    print("処理再開")

asyncio.run(example())
  • await asyncio.sleep(2)で2秒間待機し、その後処理が再開されます。
  • この間、他のタスクを実行できるため効率的に処理が進みます。

awaitとasyncの組み合わせ

非同期関数を呼び出すときには、awaitを使ってその結果を待つことができます。

# async関数をawaitで実行
import asyncio

async def task1():
    print("タスク1開始")
    await asyncio.sleep(3)
    print("タスク1完了")

async def task2():
    print("タスク2開始")
    await asyncio.sleep(2)
    print("タスク2完了")

async def main():
    await task1()  # task1が終わるまで待つ
    await task2()  # task2が終わるまで待つ

asyncio.run(main())
  • await task1()でタスク1が終わるのを待ってからタスク2を実行します。
  • この方法ではタスクが直列に実行されます。

awaitと並行処理

awaitを使うと、複数の非同期タスクを並行して実行することができます。

# 複数のタスクを並行実行
import asyncio

async def task(name, seconds):
    print(f"{name} 開始")
    await asyncio.sleep(seconds)
    print(f"{name} 完了")

async def main():
    await asyncio.gather(task("タスク1", 3), task("タスク2", 2))

asyncio.run(main())
  • asyncio.gather()を使うと、複数のタスクを並行実行できます。
  • タスク1とタスク2が同時に開始され、最も時間のかかるタスクが終わると処理が続行されます。

awaitの実践的な使用例

非同期処理を使うと、複数のWebリクエストを同時に実行できます。

# 非同期で複数のWebページを取得
import asyncio
import aiohttp  # 非同期HTTPリクエスト用ライブラリ

async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def main():
    urls = ["https://example.com", "https://example.org"]
    tasks = [fetch(url) for url in urls]
    results = await asyncio.gather(*tasks)
    for result in results:
        print(result[:100])  # 最初の100文字を表示

asyncio.run(main())
  • await response.text()を使ってWebページの内容を非同期で取得します。
  • asyncio.gather()で複数のリクエストを並行処理できます。

awaitの注意点

  • awaitはasync関数内でのみ使用可能: 通常の関数内でawaitを使うとエラーになります。
  • 非同期対応の関数のみawait可能: awaitを使うには、対象の関数がasyncである必要があります。
  • 同期処理をブロックしない: 非同期処理を効率的に扱うため、ブロッキングする処理(例: time.sleep())を避けるべきです。

awaitのよくある質問

Q: awaitを使うと処理は並列になりますか?
A: いいえ。awaitは「並列処理」ではなく「並行処理」です。処理を中断しながらタスクを切り替えますが、CPUのスレッドやプロセスは増やしません。
Q: awaitはどこでも使えますか?
A: いいえ。awaitasync関数内でのみ使用できます。通常の関数で使うとエラーになります。
Q: asyncio.run()の外でawaitを使うには?
A: Jupyter Notebookや一部の環境ではasyncio.run()を使わずに直接awaitが使用できます。

まとめ

awaitは非同期処理の完了を待ち、次の処理を実行するための重要なキーワードです。

  • awaitasync関数内で使用し、非同期処理を制御します。
  • 非同期関数の結果を待ちつつ、他の処理を並行して実行できます。
  • 効率的な非同期プログラミングを行うため、asyncio.gather()などと組み合わせて活用しましょう。

適切にawaitを活用し、非同期処理を効率よく管理しましょう。