生産者消費者モデルとは何ですか
職場では、特定のモジュールがデータの生成を担当し、そのデータが別のモジュールによって処理されるという状況に遭遇することがあります (ここでのモジュールは広範であり、クラス、関数、スレッド、プロセスなどになります)。データを生成するモジュールはプロデューサーと呼ばれ、データを処理するモジュールはコンシューマーと呼ばれます。生産者と消費者の間に緩衝地帯が追加され、これを比喩的に倉庫と呼びます。生産者は倉庫に商品を入れる責任があり、消費者は倉庫から商品を取り出す責任があります。これが生産者-消費者モデルを構成します。 。構造図は次のとおりです:
生産者消費者モデルの利点:
1. デカップリング
プロデューサーとコンシューマーがそれぞれ 2 つのクラスであると仮定します。プロデューサがコンシューマのメソッドを直接呼び出す場合、プロデューサはコンシューマに依存します (つまり、結合されます)。将来的にコンシューマのコードが変更された場合、プロデューサに影響が出る可能性があります。そして、両方が特定のバッファに依存する場合、2 つの間に直接の依存関係はなくなり、それに応じて結合が減少します。
例えば、郵便局に手紙を届けに行くとき、郵便受け(つまり緩衝地帯)を使わない場合は、郵便配達員に直接手紙を渡さなければなりません。学生の中には、郵便配達員に渡すだけで簡単ではないのではないかと言う人もいるかもしれません。実際には、それほど単純ではありません。郵便配達員に手紙を渡す前に、その郵便配達員が誰であるかを知る必要があります (郵便配達員が着ている制服に基づいて郵便配達員が偽造されたら大変なことになります)。これにより、ユーザーと Postman の間に依存関係が作成されます (プロデューサーとコンシューマー間の強い結合に相当します)。ある日郵便配達員が変わった場合には、それを再理解する必要があります (プロデューサー コードの変更につながるコンシューマの変更に相当)。メールボックスは比較的固定されており、それに依存するコストは比較的低くなります (バッファーとの弱い結合に相当します)。
2. 同時実行のサポート
プロデューサーとコンシューマーは 2 つの独立した同時実行体であるため、バッファーをブリッジとして使用して接続されます。プロデューサーはデータをバッファーにスローして次のデータの生成を続行するだけで済み、コンシューマーはデータを取得するだけで済みます。お互いの処理速度によるブロックが発生しないようにします。
上記の例の続きですが、郵便ポストを使用しない場合、郵便局員が戻ってくるまで待たなければならず、その間、私たちは何もすることができません(つまり、彼に手紙を渡すことになります)。プロデューサーがブロックしている場合)、または郵便配達員に戸別訪問して、誰が手紙を送りたいかを尋ねる必要があります(消費者の世論調査に相当)。
3. 不規則な多忙なスケジュールをサポートします
バッファには別の利点もあります。データの生成速度が速い場合と遅い場合には、バッファーの利点が反映されます。データが急速に生成されると、消費者はそれを処理する時間がなくなり、未処理のデータがバッファに一時的に保存される可能性があります。生産者の生産スピードが遅くなると、消費者は徐々に廃棄していきます。
完全に再利用するために、手紙を送る例を見てみましょう。郵便配達員は一度に 1,000 通の手紙しか運べないとします。バレンタインデー (またはクリスマス) にグリーティング カードを送り、1,000 通を超える手紙を送る必要がある場合は、メールボックスのバッファ ゾーンが役に立ちます。郵便配達員は、持ち出すのが遅すぎる手紙を、次に取りに来るまで一時的に郵便受けに保管します。
Python の例:
キューを使用して、単純なプロデューサー/コンシューマー モデルを実装します。プロデューサーは時間をキューに入れ、コンシューマーはそれが取り出されたときに時間を出力します
。
マルチスレッドを使用すると、クロールを実行するときにプロデューサーを使用して URL リンクを生成し、コンシューマーを使用してキューを利用してクロールを高速化できます。