銀河鉄道

Python【async / await】非同期処理で止まらない世界を作る

サムネイル
asynchronousasyncawait
待つときに
await

非同期が必要な理由

ネット通信・ファイル入出力・DBアクセス・ストリーミングみたいな待ち時間の長い処理を、他の処理を止めずに同時進行させるため。

基本構造(Swiftと比較)

  • async で「この関数は非同期です」って宣言
  • await で「ここで結果を待つけど、他の処理は止めないでね」

Python

async def fetch_data():
    result = await api_client.get_data()
    return result


// 使用例
asyncio.run(fetch_data())

Swift

func fetchData() async throws -> String {
    let result = try await apiClient.getData()
    return result
}


# 使用例
Task {
    await fetchData()
}

補足|Pythonは柔軟で自由、Swiftは静的で型安全

  • 構文も考え方もほぼ同じ(async関数でawait)。
  • Swiftの Task { await ... } でやる感覚は、Pythonの asyncio.run(...) とほぼ同等。
  • 違いは実行基盤(スレッド管理)
要素PythonSwift
並列実行asyncio.gather, asyncio.create_taskTask, TaskGroup
スレッド管理イベントループ(asyncio)OSが最適化(GCD)
エラーハンドリングtry / excepttry / catch
戻り値型何でもOK(動的)明示的 (async throws -> T)

例えばこんな用途で使う

  • ノンブロッキング I/O
    • 待ってる間、スレッドを占有しない。カクつきにくい。
  • 並行実行(concurrency)
    • 複数の待ちを同時にさばく(API×複数、DB+キャッシュなど)
  • ストリーミング対応
    • 生成AIのトークン出力や大容量DLを流しながら返せる
  • キャンセル/タイムアウト
    • 遅い処理を途中で見切る、切断時に即やめられる
  • スケール効率
    • 同期実装より同時接続数を稼ぎやすい(特にWebサーバ)。

具体例

  • HTTP/API 通信(外部サービス呼び出し・Webhook受信)
  • DB/キャッシュ I/O(Redis・非同期ドライバ・複数クエリ並列)
  • ファイル/クラウドストレージ I/O(アップロード/ダウンロード)
  • メッセージング(WebSocket、SSE、キュー処理)
  • 生成AIのストリーミング(トークンが来るたび即表示)

待ちが多い処理」=asyncの出番!

コード感覚(同期 vs 非同期)

同期(ブロッキング:待ってる間は他が止まる)

def handle_request():
    data = http_get("https://api.example.com/data")   # ← 帰ってくるまで待つ
    save_to_disk(data)                                 # ← 書き込み完了まで待つ
    return "done"

非同期(ノンブロッキング:待ちを並列化)

import asyncio

async def handle_request():
    task_net = asyncio.create_task(http_get_async("https://api.example.com/data"))
    task_log = asyncio.create_task(write_access_log_async())
    data, _ = await asyncio.gather(task_net, task_log)  # ← 並行で待つ
    await save_to_disk_async(data)
    return "done"

設計ポイント

  • I/Oは極力async対応ライブラリを選ぶ(HTTP, DB, ファイル)。
  • asyncio.gatherで「待ち」を束ねてTTFT(最初の応答)を短縮
  • asyncio.timeoutで遅延の見切りを入れる(フォールバック設計)。
  • キャンセル伝播:親タスク中断で子タスクも止める(ゾンビ防止)。
  • 境界を決める:UI層・API層はasync、CPU重たい処理は別プロセス/スレッドへ。

逆に、どんな時は不要?

  • CPU計算が主役(数値最適化、画像処理、学習ループ)
    → asyncより並列化(multiprocessing / GPU)を検討。
  • 単発の短いスクリプト(待ちがほぼ無いバッチ)
    → 同期でシンプルに書いたほうがメンテしやすい。

Vocabulary

  • asynchronous | 非同期の
  • event loop | イベントループ
  • coroutine | コルーチン(非同期タスクの単位)
  • concurrent | 並行
  • blocking / non-blocking | ブロックする / しない

Async isn’t just for going faster;
it’s for keeping things flowing
without stops.

Swiftの場合

著者

author
月うさぎ

編集後記:
この記事の内容がベストではないかもしれません。

記事一覧