3

次の問題に遭遇し、続行する方法を決定できません。

1/T 秒ごとにデータのチャンクを取得するクラスがReaderあります (実際には、データはビデオ フレームからのもので、1 秒あたり 30 フレームです)。Detectorsチャンクは、チャンクを処理して決定を出力するいくつかのオブジェクトに渡されます。ただし、各検出器が決定を下す前に読み取る必要があるチャンクの数はさまざまです。たとえば、チャンクが 1 つだけ必要な場合もあれば、51 個のチャンクが必要な場合もあります。

Reader読み取りデータチャンクを配置するデータバッファーを用意し、パブリッシュ/サブスクライバーを実装してそれぞれを登録Detectorし、データバッファーに処理するのに十分な数のフレームがある場合に信号を送信することを考えています。これは良いアプローチですか?Detectorsまた、バッファを管理し、独自のコピーを作成せずにバッファからデータを読み取る最良の方法は何ですか? 共有ポインタ?

どうもありがとう!

4

3 に答える 3

4

リングバッファ/循環キューを調べます。これにより、必要な最大数のフレームを保持するのに十分な大きさの初期バッファー サイズを作成する場合、1 回限りのメモリ割り当てで必要なことを行うことができます。

バッファへのアクセスの管理に関しては、データの準備ができたときのシグナリングとリーダーとのポインタの共有は機能しますが、複数のスレッドを使用している場合は、何らかのタイプの同期が必要になります。プロデュース コンシューマの問題を参照してください。

于 2009-10-19T20:07:12.260 に答える
2

私は最近、あなたが説明しているものと同様の何かを実装しました。

boost :: interprocessライブラリ(詳細についてはboost.org)を強くお勧めします。

あなたが探しているのはboost::interprocess/managed_shared_memoryです。最初は少し奇妙に見えるでしょうが、一度コツをつかめば、きっと気に入るはずです。

実行したいことは次のとおりです。管理された共有メモリセグメントを作成します。void_allocatorを使用してプロセス間通信を処理するオブジェクトを割り当てます(アロケータを検索します)。同期メカニズムを実装します(たとえば、boost :: interprocess:semaphore&boost :: interprocess_mutex)。管理された共有メモリを介して、別々のプロセスからの通信を実装します。

于 2009-10-19T21:12:44.930 に答える
2

(Maciek へのコメントにも基づいて) スレッドとプロセスの違いと、それらがどのように通信できるかを理解することから始めなければならないと思います。

デザインの問題について: シンプルなデザインから始めてみてください。たとえば、スレッドのみを使用し、各サブスクライバーに、独自の同期キューを使用してジョブに shared_ptr を渡します*。データへのアクセスは読み取り専用であり、AFAICR では、boost::shared_ptr はそのような使用に対して安全なマルチスレッドであるため、同期の問題はなく、データは自動的に消去されます。(まだ)メモリの再割り当てについて心配する必要はありません。サブスクライバ/スレッドごとに有限量のメモリ(o(1))(あなたが言ったように、最大​​で約51個のshared_ptrs)を使用していることを確認してください。

この動作するスケルトンができたら、遭遇した問題に基づいて最適化を開始できます。再割り当てが問題の場合は、リング バッファーに移動できます (bcat で提案されているように)。または、アロケータ (/new 演算子) をプール アロケータに置き換えることができます。サブスクライバが多数ある場合は、すべてのスレッドで使用される単一のキューにキューをマージすると効果的です。これを行うには、より多くの情報が必要です (非常に長い計算のために 1 つのスレッドが非常に遅い場合はどうなりますか? 処理を停止するようにスレッドに通知する方法はありますか? または、キューが大きくなる必要がありますか? この場合、循環バッファーは機能しない可能性がありますまあまあ...) 複雑になるかもしれませんが、(ジョブではなく) shared_ptrs によって占められている部屋を保存しようとしているだけであることを忘れないでください。

要するに、時期尚早の最適化を避けるようにしてください。代わりに、合理的な最適化と拡張性を備えた設計を作成し、学んだことに基づいてそこから先に進みます。

幸運を

* 同期キュー - スレッド間のキュー。push(j) はジョブを追加し、pop() はキューが空でなくなるまで待機し、一番上のジョブを返します(stl::queue とは異なります。キューが複数のスレッドによって読み取られる場合、これは重要です)。通常、stl::queue をラップし、boost::mutex を使用して保護することで実装します。

于 2009-10-19T23:39:38.563 に答える