web-dev-qa-db-ja.com

ジェネレーターよりもいつコルーチンを使用するのですか?

データのパイプライン処理は、次のいずれかで実行できます。

ジェネレータを使用するのみ

enter image description here

パイプラインのジェネレーターの例:

_def grep(source, pattern=None):
   patternObject = re.compile(pattern)
   for line in source:
      if patternObject.search(line):
         yield line
_

または

コルーチンの使用のみ

enter image description here

パイプラインのコルーチンの例:

_@coroutine
def grep(pattern):
   print "Looking for %s" % pattern
   while True:
      line = (yield)
      if pattern in line:
         print line,
_

ジェネレーターは、スレッドを使用して、複数のソースからのデータを多重化するために使用できます。

enter image description here

ジェネレーターを使用して、データを複数のコンシューマーにブロードキャストできます。

enter image description here

ジェネレーターは並行プログラミングでも同等に強力です


質問:

なぜsend()(ex:python)を使用してクールーチンが必要なのですか?ジェネレーターよりもいつコルーチンを使用するのですか?

5
user1787812

コルーチンareジェネレーター -呼び出し後に引数を受け取る追加機能を備えています。

データパイプライン(ETLに関するもの)は、その長所を示す良い例です。パイプラインがコルーチンの全機能を必要とすることはめったにありません。データは静的で不変であり、データとカプセル化関数のコンテキスト外で動的に変更する必要はありません。

ただし、コルーチンを使用する理由は確かにあります。 2つの例:

  1. 新しいコンテキストの動的インジェクション:複数の受信サーバーリクエストを処理する必要があり、リクエストごとのプロセスモデルを回避したいa laApache。コルーチンを相互にインターリーブし、任意のポイントでリクエスト(cookie、セッションなど)のcontextを渡すと、メリットを得ることができますN:M要求ごとのプロセスモデルを使用して、アドホック間隔で提供できる新しい構成を使用して要求を動的に評価します。

  2. ジェネレーター間通信:各ジェネレーターがtalk何らかの方法で他の人に。たとえば、コルーチン全体を調整してリソースを節約しようとしているのかもしれません。あるいは、time.time()の呼び出しではなく、Lamportベクトルクロックを使用したいのかもしれません。純粋なジェネレーターはreturn値のみを受け入れることができましたが、新しい構成または入力値を受け入れることはできません-コルーチンはできます。

この機能が必要なときはいつでも、コルーチンは役に立ちます!

8
Akshat Mahajan