2

次のシナリオのデータ構造を探しています。

  1. スレッドのプールは、データのチャンクのファイルタイプを分類する必要があります
  2. 各スレッドは、この(ブロッキング)データ構造から読み取ります
  3. もう1つのスレッド(スレッドプールの一部ではない)は、ストレージデバイスからブロックを読み取り、それらをデータ構造にフィードします。
  4. 使用可能なデータがなくなると、読み取りスレッドはデータ構造に通知(または割り込み)するため、プールからブロックされたスレッドは終了してシャットダウンできます。

ここでは、ブロッキングFIFOキューが適切/十分だと思いますか?もう1つの要件は、データ構造がオープンソースとして利用可能であり、さまざまなオペレーティングシステム(少なくともWindows / Linux)用にコンパイルできることです。

APR Utilライブラリは一見有望に見えましたが、Visual Studioのプロジェクトファイルは、このコンパイラスイートの先史時代のバージョンを対象としています。

4

2 に答える 2

1

生産者/消費者FOFOブロッキングキューは合理的と思われます。すべてのマルチスレッドOSには、PCキューを作成するための適切なセマフォ/ミューテックス/コンドバー/その他があり、1つのOS固有のインターフェイスユニットで定義できます。

私が使用する「データ構造」は、データチャンクとチャンクの処理に必要なその他のメタデータを含むことができる*SomeStructのキューです。

この種のことを行うとき、私は通常、アプリの起動時にmalloced / calloced * SomeStructでいっぱいになる大きな「プールキュー」(別のPCキュー)を作成します。次に、スレッドは* SomeStructsをプールから読み取りスレッド、スレッドプールFIFO、処理スレッドに循環させ、最後にプールキューに戻します。このフロー制御により、データが暴走するのを防ぎ、継続的なmalloc/freeを排除します。

編集:

はい、FOFOはFOOBARでした。

私の設計では、2つのFIFO、スレッドセーフ、ブロッキングキューを使用しています。

a)プールキュー。起動時に固定数のmalloced /calloced*SomeStructsで満たされます。

b)処理スレッドが待機する処理キュー。

読み取りスレッドは、プールキューから* SomeStructsをデキューし、それらをロードし、処理スレッドがそれらを取得する処理キューにキューに入れ、処理し、すべて完了したら、プールキューに再キューイングします。

つまり、SomeStructsの数は起動時に作成された数に制限されるため、アプリの実行中にこれ以上malloc/callocまたはfreeを実行する必要はありません。また、読み取りスレッドが処理スレッドの「先を行く」ことを試みると、プールキューは空になり、処理スレッドが再利用のためにプールに「使用済み」*SomeStructsを返すまで読み取りスレッドはブロックされます。その後、読み取りスレッドが再度実行されます。

もう1つの利点は、複雑な制限付きキューが必要ないことです。* SomeStructインスタンスの総数は、起動時に作成された数に制限されているため、キューはその数を保持するのに十分な大きさである必要があります。これ以上保持する必要はありません。したがって、単純な固定サイズの* SomeStruct [CtotalInstances]配列はキューの基礎として適切であり、配列がいっぱいであるかどうかのインデックスのチェックを行う必要はなく、追加のセマフォを使用して'をカウントする必要もありません。空きスペース':)

ああ-シャットダウン-私はおそらくスレッドをシャットダウンすることを気にしないでしょう。彼らがすることが何もない場合、彼らはアプリが閉じられるまで何もせずにただそこに座ることができます。本当に処理スレッドをシャットダウンする必要がある場合は、受信スレッドにピルをプッシュバックするように指示するキューで、「poisonpill」メッセージを送信します(nullポインターは適切なピルです-解放する必要はありません)。キューを作成してからクリーンアップして終了します。短い順序で、すべての処理スレッドがピルを取得して自殺します。

于 2012-09-03T15:21:26.370 に答える
1

確かに、ブロッキングキューは生産者/消費者パターンに最適です。ポータブルなものが必要な場合は、Intel TBB、具体的にはtbb::concurrent_bounded_queueを試してください。

于 2012-09-03T18:19:57.747 に答える