今日、boost::circular
バッファのイテレータが、マルチスレッド環境で期待どおりに動作していないことを発見しました。(公平を期すために、シングルスレッドプログラムでも私が考えるよりも動作が異なります)。
特定のデータ シーケンスをループするために使用するイテレータを呼び出してbuffer.begin()
表す場合。buffer.end()
にさらにデータが追加されると、終了イテレータの値が変化しますcircular_buffer
。end()
データが変更された後に別の呼び出しを行った場合、明らかに異なる結果が得られると予想されます。しかし、紛らわしいのは、既に変更した iterator オブジェクトの値です。
circle_buffer 内の設定された範囲のデータを操作できるイテレータを作成し、範囲の操作中に追加のデータがバッファに追加されても値が変更されないようにする方法はありますか?
そうでない場合、適用される可能性のある推奨される「非反復子」パターン、またはこれを許可する別のコンテナー クラスはありますか?
#include "stdafx.h"
#include <boost\thread.hpp>
#include <boost\thread\thread_time.hpp>
#include <boost\circular_buffer.hpp>
int _tmain(int argc, _TCHAR* argv[])
{
boost::circular_buffer<int> buffer(20);
buffer.push_back(99);
buffer.push_back(99);
buffer.push_back(99);
boost::circular_buffer<int>::const_iterator itBegin = buffer.begin();
boost::circular_buffer<int>::const_iterator itEnd = buffer.end();
int count = itEnd - itBegin;
printf("itEnd - itBegin == %i\n", count); //prints 3
/* another thread (or this one) pushes an item*/
buffer.push_back(99);
/*we check values of begin and end again, they've changed, even though we have not done anything in this thread*/
count = itEnd - itBegin;
printf("itEnd - itBegin == %i\n", count); //prints 4
}
ronag へのより詳細な応答の更新 プロデューサー コンシューマー タイプ モデルを探しています。ブースト ドキュメントに示されている制限付きバッファーの例は、必要なものに近いものです。ただし、次の 2 つの例外があります。
バッファから一度に複数のデータ要素を読み取り、それらを検査できる必要がありますが、これは簡単ではないかもしれません。次に、バッファから削除するアイテムの数を選択します。
偽の例: 文字列から hello と world という 2 つの単語を処理しようとしています。
1 を読み取り、バッファに hel が含まれています。バッファから文字を削除しません。-more 読み取り 2 を生成、バッファには hellowo が含まれています。「hello」が 5 文字を削除していることがわかりました。バッファには wo が含まれています。さらに読み取り 3 を生成します。バッファには world が含まれています。
バッファーがいっぱいでない限り、読み取り時にプロデューサー スレッドをブロックする必要はありません。