コルーチン こるーちん
簡単に言うとこんな感じ!
コルーチンは「途中で一時停止して、あとで再開できる関数」のことだよ!普通の関数は呼び出したら最後まで一気に走るけど、コルーチンは「ちょっと待ってて!」って止められて、また続きから動かせるんだ。料理しながら洗濯機を回すみたいな”ながら作業”をプログラムで実現できる仕組みってこと!
コルーチンとは
コルーチン(Coroutine)とは、実行を途中で一時停止(サスペンド)し、あとで再開できるプログラムの実行単位のことです。“Co-routine”という名前は「協調して動くルーチン(関数)」という意味を持ちます。通常の関数(サブルーチン)が「呼び出し→実行→返却」という一方通行なのに対して、コルーチンは呼び出し元と呼び出し先が互いに制御を譲り合いながら動くことができます。
ビジネスの現場では、Webアプリのデータ取得・ファイルの読み書き・APIの呼び出しなど、待ち時間が発生する処理を効率化する手段としてコルーチンが活用されています。KotlinやPython、JavaScriptなど多くのモダンな言語に組み込まれており、システム開発の発注仕様を確認するときに「async/await(非同期処理)を使っています」と書かれていたら、その裏側にコルーチンの概念が使われていると思って間違いありません。
コルーチンの最大のメリットは、スレッド(独立した実行の流れ)を大量に作らなくても、並行処理を実現できる点です。スレッドはOSが管理するため生成コストが高いのですが、コルーチンはプログラム側で管理するため非常に軽量です。数万~数十万のコルーチンを同時に動かすことも現実的にできます。
コルーチンの仕組みと構造
コルーチンを理解するには「通常の関数との違い」を押さえるのが一番の近道です。
| 比較項目 | 通常の関数(サブルーチン) | コルーチン |
|---|---|---|
| 実行の流れ | 呼び出し→一気に最後まで実行 | 途中で一時停止・再開が可能 |
| 制御の主体 | 呼び出し元が一方的に制御 | 呼び出し元と呼び出し先が協調 |
| 状態の保持 | 終了後は状態が消える | 停止中も状態(変数など)を保持 |
| 並行実行 | 同時に複数動かすにはスレッドが必要 | 1スレッド上で複数を切り替えられる |
| 代表的な用途 | 計算処理・変換処理など | 非同期I/O・アニメーション・ゲームなど |
コルーチンの状態遷移
コルーチンは以下の3つの状態を行き来します。
┌─────────┐ 呼び出し ┌─────────┐
│ 待機中 │ ──────────► │ 実行中 │
│(Created) │ │(Running) │
└─────────┘ └────┬────┘
▲ │ サスペンド(一時停止)
│ 再開 ▼
┌─────────┐ ┌─────────┐
│ 再開待ち │ ◄────────── │ 停止中 │
│(Resumed) │ │(Suspended)│
└─────────┘ └─────────┘
覚え方:「コルーチン=コラボするルーチン」
「コラボするルーチン」と覚えましょう。関数同士が交互に制御を渡し合いながら協力して動くイメージです。コラボ(Co-)というプレフィックスが「協調」を表しているとイメージすると、通常の関数との違いが直感的につかめます。
主な言語での実装例
| 言語 | 書き方のキーワード | 代表的な用途 |
|---|---|---|
| Python | async def / await / yield | データ取得・スクレイピング |
| JavaScript/TypeScript | async / await / function* | Webフロントエンド・Node.js |
| Kotlin | suspend / launch / async | Androidアプリ開発 |
| Go | goroutine / channel | サーバーサイド・マイクロサービス |
| C# | async / await | .NETアプリ・Unity |
歴史と背景
- 1958年 — コンピューターサイエンスの先駆者 メルビン・コンウェイ(Melvin Conway) がコルーチンの概念を提唱。アセンブリ言語のコンパイラ設計で活用したことが始まり
- 1963年 — コンウェイが論文 “Design of a Separable Transition-Diagram Compiler” で正式に概念を発表
- 1970年代〜1980年代 — COBOLやSimulaなどに影響を与えるも、主流にはならず。スレッドモデルが並行処理の主流に
- 1990年代〜2000年代 — Pythonにジェネレーター(
yield)が導入され、コルーチンの前身となる仕組みが普及し始める - 2012年 — C# 5.0で
async/awaitが導入され、コルーチンベースの非同期処理がエンタープライズ開発に普及 - 2015年 — JavaScript(ES2017)でも
async/awaitが標準化に向けて動き出し、Webフロントエンド開発でも一般化 - 2018年〜現在 — KotlinのCoroutines、Pythonのasyncioなどモダンなフレームワークがコルーチンをファーストクラスの機能として採用。スマホアプリ・サーバーサイドの両方で標準的な手法に
スレッドとの違い・非同期処理との関係
コルーチンと混同しやすい概念が「スレッド」と「非同期処理」です。それぞれの関係を整理します。
async/await との関係
async/await という書き方は、コルーチンを人間にとって読みやすい形で書くための構文です。裏側ではコルーチンのサスペンド・再開が行われています。
# Pythonの例:コルーチンを使った非同期処理
import asyncio
async def データ取得(url):
print(f"{url} の取得を開始...")
await asyncio.sleep(2) # ← ここで一時停止(他の処理に制御を渡す)
print(f"{url} の取得が完了!")
return "データ"
async def メイン():
# 2つのコルーチンを同時に実行(どちらかが待つ間に他方が動く)
await asyncio.gather(
データ取得("https://api.example.com/A"),
データ取得("https://api.example.com/B"),
)
asyncio.run(メイン())
# → 2秒待つのは1回だけ!(逐次実行なら4秒かかるところを2秒に短縮)