データのストリームを生成する機器があります。私のコードは callback を介してこのデータにアクセスしますonDataAcquisitionEvent(const InstrumentOutput &data)
。データ処理アルゴリズムは、データの到着速度よりも大幅に遅くなる可能性があるため、すべてのデータを処理することは期待できませんが (そうする必要はありません)、できるだけ多くのデータを処理したいと考えています。私が制御できないデータ取得速度を備えた環境センサーとしての機器に感謝します。InstrumentOutput
たとえば、異なる場所での 3 つの同時圧力測定値を含むクラスである可能性があります。
また、データの簡単な履歴を保持する必要があります。たとえば、データのサンプルを 200 ミリ秒ごとに処理することが合理的に期待できると仮定します。ほとんどの場合、最後のサンプルを 1 つだけ処理しても問題ありませんが、最後のサンプルに異常な読み取り値が存在するかどうかに応じて、その最新のサンプルの前に到着した数秒分のデータを確認する必要がある場合があります。
onDataAcquisitionEvent()
もう 1 つの要件は、センサーでのデータ損失を回避するために、できるだけ早くコールバックから抜け出すことです。
データ取得ライブラリ (サードパーティ) は、別のスレッドで機器データを収集します。
次のデザインを考えました。単一のプロデューサー/単一のコンシューマー キューを持ち、データ トークンを onDataAcquisitionEvent() コールバックの同期キューにプッシュします。
受信側では、キューからデータをポップするループがあります。データ到着率が高いため、ループはほとんどスリープしません。各反復で、次のことが起こります。
- 利用可能なすべてのデータをキューからポップし、
- ポップされたデータは循環バッファーにコピーされます (ブースト循環バッファーを使用しました)。このようにして、履歴が常に利用可能になります。
- バッファ内の最後の要素を処理します (そして、前の要素を調べる可能性があります)。
- ループを繰り返します。
質問:
- この設計は適切ですか? また、落とし穴は何ですか? と
- より良いデザインは何でしょうか?
編集:私が考えた1つの問題は、循環バッファのサイズが必要な履歴を保持するのに十分な大きさではない場合です。現在、単純に循環バッファーを再割り当てして、そのサイズを 2 倍にしています。1回か2回だけでいいと思います。