はじめに
定義
コンピューター・サイエンスにおいて、ルーチンとは命令の連なりのことであると定義されます。複数のルーチンの実行が親子関係を形づくり、子は必ず親よりも先に終了します。コルーチン(この用語はメルヴィン・コンウェイが導入1)は、ルーチンを一般化したものです(ドナルド・クヌース2)。コルーチンとルーチンの主な違いは、コルーチンがその進行の停止と再開を明示的に行えることにあります。これは、追加の命令で実行状態を保存することで行えます。したがって、強化された制御フロー(実行コンテキストを管理します)を提供するのです。
仕組み
関数 foo()
と bar()
が、それぞれ代わる代わる実行(関数の本文を抜けたり入ったりする)されてほしいです。
もしコルーチンがルーチンと全く同じように呼びだされたなら、スタックは呼び出されるごとに伸び、ポップされることはないでしょう。リターンアドレスがスタックエントリの一番上でしょうから、コルーチンの中間にジャンプすることが出来ないのです。
解決法は、各コルーチンが自身のスタックとコントロールブロック(Boost.Contextのboost::contexts::fcontext_t
)を持つことです。コルーチンが停止される前に、現在アクティブなコルーチンのvolatileでないレジスタ(スタックと命令・プログラムポインターを含みます)をそのコルーチンのコントロールブロックに保存します。新しく作動したコルーチンのレジスターは、再開する前に関連付けられたコントロールブロックから回復される必要があります。
コンテキストスイッチはシステム特権を必要としないので、C++に便利な協調的マルチタスクを提供します。コルーチンは擬似並列処理を提供します。プログラムに幾つかのことを同時に行わせたいとき、コルーチンはこれを単一の制御フローを用いるよりも簡潔かつ優雅に行う助けになります。利点は特に再帰関数を用いた時に明らかになります。例えば二分木をトラバーサルするときです(例「same fringe」を参照)。
特性
コルーチンの特性3は:
- ローカルデータの値が連続する呼び出し(コンテキストスイッチ)の間で持続する
- 実行の停止はコントロールがコルーチンを残すことで行われ、後に再開される
- 対称あるいは非対称コントロール移動機構(以下を参照)
- 一級オブジェクト(引数として渡せて、returnで返せて、データ構造に保存して後で使えて、開発者が自由に操作できる)
- スタックフルまたはスタックレス
コルーチンは、協調タスク(ファイバー)、イテレーター、ジェネレーター、無限リスト、パイプなどのコンポーネントの実装をサポートするので、シミュレーション、人工知能、並行プログラミング、テキスト処理、データ操作と言った領域で便利です。
実行移動機構
2つのカテゴリのコルーチンがあります。対称と非対称です。
非対称コルーチンはその呼び出し元を知っていて、暗黙的に呼び出し元へコントロールを譲る特別な命令を使えます。それに対して、すべての対称コルーチンは同等です。1つの対称コルーチンがどれか他の対称コルーチンにコントロールを渡します。よって、対称コルーチンは必ず、コントロールをどのコルーチンに譲るか明示する必要があります。
両方の概念は等しいものなので、完全に一般的なコルーチンライブラリーは対称と非対称のどちらのコンセプトも提供できます。
スタックフル性
スタックレスコルーチンに対して、スタックフルコルーチンはネストしたスタックフレームの内側から停止できます。実行はコードの前回停止した場所と正確に同じ地点から再開されます。スタックレスコルーチンの場合は、トップレベルのルーチンだけが停止されます。いかなるトップレベルのルーチンから呼ばれたルーチンも、自身を停止しません。これは停止・再開操作を汎用的なライブラリー内のルーチンに提供することを不可能にします。
一級継続
一級継続は引数として渡したり、関数から返されたり、データ構造に保存してあとから使うことが出来ます。幾つかの実装(例:C#のyield
)においては、継続は直接アクセスしたり、直接操作したり出来ません。
スタックフル性と一級セマンティクス無しには、いくつかの便利な実行コントロールフローをサポートできません(例えば、協調的マルチタスクやチェックポイントです)。
1. Conway, Melvin E.. "Design of a Separable Transition-Diagram Compiler". Commun. ACM, Volume 6 Issue 7, July 1963, Article No. 7 ↩
2. Knuth, Donald Ervin (1997). "Fundamental Algorithms. The Art of Computer Programming 1", (3rd ed.) ↩
3. Moura, Ana Lucia De and Ierusalimschy, Roberto. "Revisiting coroutines". ACM Trans. Program. Lang. Syst., Volume 31 Issue 2, February 2009, Article No. 6 ↩