1

アプリケーションで6つのスレッドを継続的に実行しています。シナリオは次のとおりです。

1つのスレッドが継続的にメッセージを取得し、メッセージキューに挿入します。他の4つのスレッドは、キューからメッセージを継続的にフェッチして処理するワーカーと見なすことができます。もう1つの最後のスレッドは、分析情報を入力します。

問題:

現在、メッセージスレッドを取得するためのスリープ時間は100msです。ワーカースレッドは200msです。このアプリケーションを実行すると、メッセージフェッチスレッドが制御を取得してキューに挿入し、ヒープを増やします。ワーカースレッドは、メッセージを処理して割り当てを解除する機会を得ていません。最後に、その結​​果、メモリが不足します。

メッセージフェッチスレッドとワーカースレッドに機会均等が与えられるように、この種のシナリオを管理する方法。

前もって感謝します :)

4

4 に答える 4

4

プロデューサースレッドにバックプレッシャを追加する必要があります。通常、これはブロッキングコンシューマープロデューサーキューを使用して行われます。プロデューサーはアイテムをキューに追加し、コンシューマーはアイテムをキューからデキューして処理します。キューが空の場合、プロデューサーがキューに何かを追加するまで、コンシューマーはブロックします。キューがいっぱいの場合、コンシューマーがキューからアイテムをフェッチするまでプロデューサーブロック。

于 2012-12-19T11:44:07.607 に答える
4

私がよく使用するフロー制御システムの 1 つは、起動時にメッセージ オブジェクトの大きなプールを作成し、それ以上作成しないというものです。*オブジェクトは、スレッド セーフなブロッキング 'プール キュー' に格納されて循環し、プロデューサーによってプールからポップされ、他のブロッキング キューのコンシューマーにキューイングされ、'消費' されたときにプール キューにプッシュされます。 .

これにより、メモリの使用量が制限され、フロー制御が提供され (プールが空になると、メッセージがコンシューマーから返されるまでプロデューサーがブロックします)、継続的な new/delete/malloc/free が排除されます。より複雑で低速な制限付きキューは必要なく、すべてのキューが、(既知の) 最大メッセージ数を保持するのに十分な大きさであればよいだけです。

「クラシック」ブロッキング キューを使用する場合、Sleep() 呼び出しは必要ありません。

于 2012-12-19T12:14:03.007 に答える
1

制限付きキューを使用すると、いっぱいになると、より多くのスペースが使用可能になるまで、エンキューしようとするスレッドがブロックされます。

tbbからconcurrent_bounded_queueを使用するか、最大キューサイズに初期化されたセマフォを使用して、エンキューでデクリメントし、デキューでインクリメントすることができます。boost :: threadはセマフォをネイティブに提供しませんが、ロックと条件変数を使用して実装できます。

于 2012-12-19T11:42:49.867 に答える
1

あなたの質問は少し曖昧なので、コードの代わりにこれらのガイドラインを与えることができます:

  1. Mutexで相互データを保護します。マルチスレッドの消費者プロデューサーの問題では、通常、相互データ(プログラム内のメッセージ)に競合状態があります。一方のスレッドが相互メモリの場所に書き込もうとしているのに対し、もう一方のスレッドは同じ場所から読み取りを試みています。リーダーが読み取ったメッセージは、読み取りプロセスの途中でライターが上書きしたため、破損している可能性があります。Mutexを使用して相互メモリの場所をロックできます。相互データを読み取ったり変更したりできるようにするには、各スレッドがこのロックを取得する必要があります。このようにして、コンシューマープロセスは、データが変更されていないことを完全に確認します。ただし、このロックを取得するとプロデューサースレッドが抑制される可能性があるため、できるだけ早くロックを解除する必要があることに注意してください。
  2. 条件変数を使用して、コンシューマースレッドに通知します。通知メカニズムを使用しない場合、すべてのコンシューマスレッドは、システムリソースを消費するデータ生成を積極的にチェックする必要があります。コンシューマースレッドは、メッセージの準備ができるたびにプロデューサースレッドが通知することを知っているので、簡単にスリープ状態になるはずです。

C ++ 11のスレッドライブラリには、コンシューマプロデューサアプリケーションを実装するために必要なすべてのものが含まれています。ただし、コンパイラをアップグレードできない場合は、ブーストスレッドライブラリを使用することもできます。

于 2012-12-19T13:23:42.703 に答える