54

コルーチンの概念は非常に興味深いように思えますが、実際の生産的な環境で意味があるかどうかはわかりません。コルーチンの実装が他の方法よりもエレガント、シンプル、または効率的であるコルーチンのユースケースは何ですか?

4

7 に答える 7

53

1 つのユース ケースは、複数の同時接続を持つ Web サーバーであり、それらすべてと並行して読み取りと書き込みをスケジュールする必要があります。

これは、コルーチンを使用して実装できます。各接続は、ある程度の量のデータを読み書きし、スケジューラに制御を渡すコルーチンです。スケジューラーは次のコルーチン (同じことを行います) に進み、すべての接続を循環します。

于 2008-11-20T00:00:42.267 に答える
25

Unix パイプは使用例です。

grep TODO *.c | wc -l

上記のパイプラインはコルーチンです。このgrepコマンドは一連の行を生成し、それらをバッファーに書き込みます。このwcコマンドは、これらの行をバッファーから読み取ります。バッファがいっぱいになるとgrep、バッファが空になるまで「ブロック」します。バッファが空の場合は、バッファwcでさらに入力を待ちます。

コルーチンは、前述の Python ジェネレーターのように、またはパイプラインとして、より制約されたパターンで使用されることがよくあります。

詳細と例については、ウィキペディアの記事、特にコルーチンイテレータを参照してください。

于 2008-11-20T03:26:43.710 に答える
20

真のコルーチンには言語サポートが必要です。それらはコンパイラによって実装され、基礎となるフレームワークによってサポートされる必要があります。

言語でサポートされているコルーチンの実装の 1 つは C# 2.0yield returnキーワードです。これにより、ループ用に複数の値を返すメソッドを記述できます。

yield returnただし、制限があります。この実装ではヘルパー クラスを使用して状態をキャプチャし、ジェネレーター (イテレーター) としてコルーチンの特定のケースのみをサポートします。

より一般的なケースでは、コルーチンの利点は、特定の状態ベースの計算を表現しやすく理解しやすくすることです。たとえば、ステート マシンを一連のコルーチンとして実装すると、他の実装よりも洗練されたものになる可能性があります。ただし、これを行うには、C# や Java にはまだ存在しない言語サポートが必要です。

于 2008-11-19T23:23:57.817 に答える
15

コルーチンは、プロデューサー/コンシューマー パターンの実装に役立ちます。

たとえば、Python はジェネレーターと呼ばれる言語機能にコルーチンを導入しました。これは、イテレーターの実装を簡素化することを目的としていました。

また、各タスクがスケジューラー/リアクターに譲るコルーチンである協調マルチタスクの実装にも役立ちます。

于 2008-11-19T23:31:14.170 に答える
11

コルーチンは、システムが2つ以上のタスクを実行する場合に役立ちます。これらのタスクは、多くの待機を伴う一連の長時間実行ステップとして最も自然に記述されます。

たとえば、LCDとキーパッドのユーザーインターフェイスとモデムを備えたデバイスを考えてみます。モデムを使用して、キーパッドのユーザーが行っていることとは関係なく、定期的に呼び出してステータスを報告する必要があります。ユーザーインターフェイスを作成する最も良い方法は、「input_numeric_value(&CONV_SPEED_FORMAT、&conveyor_speed);」のような関数を使用することです。これは、ユーザーが値を入力したときに返されます。通信を処理する最も良い方法は、「wait_for_carrier();」のような関数を使用することです。これは、ユニットが接続されているか、接続されていないと判断されたときに戻ります。

コルーチンがない場合、UIサブシステムまたはモデムサブシステムのいずれかをステートマシンを使用して実装する必要があります。コルーチンを使用すると、両方のサブシステムを最も自然なスタイルで作成できます。サブシステムが「一貫性のある」状態になってyield()を呼び出さずに非常に長くなることも、最初に「一貫性のある」状態にせずにyield()を呼び出すことも重要ですが、通常、これらを満たすことは難しくありません。制約。

本格的なマルチタスクを使用することもできますが、共有状態が変更されるほとんどすべての場所で、ロックまたは他の相互排除構造を広く使用する必要があることに注意してください。コルーチンスイッチャーはyield()呼び出しを除いて物事を切り替えることはないため、次のyieldの前にすべてが正常に行われ、他のルーチンが状態を変更する準備ができている限り、どちらのルーチンも共有状態を自由に変更できます。 「yield()」の間に。

于 2010-07-14T15:52:35.087 に答える
7

プロデューサー/コンシューマーの例として、コルーチンを使用してバッチ レポート プログラムを実装します。

その例の重要なヒントは、入力データを消費するための重要な作業 (データの解析やアカウントへの料金と支払いの蓄積など) と、出力を生成するための重要な作業を行うことです。これらの特徴がある場合は、次のようになります。

  • 作業単位をいろいろなところに書いていただけると、入力側のコードを整理・理解しやすいです。
  • 同様に、ネストされた制御構造で次の作業単位を読み取ることができれば、出力側のコードを整理/理解するのは簡単です。

その場合、コルーチンとキューはどちらも自由に使用できる優れた手法です。

于 2009-02-04T18:20:32.980 に答える