スレッドは、別のスレッドによって非同期に追加されている要素 v[i] を待たなければならないことがあります。次のような表現で待機することができます。
i<v.size() まで待機する。この後、v[i] は割り当てられますが、おそらく構築されません。
v[i] が構築されるのを待つ。
ステップ 2 を行う最適な方法は、要素のアトミックフラグがゼロ以外になるのを待つことです。要素全体がフラグの場合もあります。要素が構築されるまでフラグがゼロであることを保証するには、次の操作を行います。
tbb::zero_allocator のような、ゼロに設定されたメモリーを割り当てるアロケーターで concurrent_vector を具体化します。
要素コンストラクターが最後のアクションでフラグをゼロ以外に設定するようにします。
次のサンプルでは、ベクトル要素がアトミックポインターです。ベクトルに追加されるポインターはゼロ以外であると仮定しているため、フラグはポインターそのものです。
#include ″tbb/compat/thread″ #include ″tbb/tbb_allocator.h″ // ここで zero_allocator を定義 #include ″tbb/atomic.h″ #include ″tbb/concurrent_vector.h″ using namespace tbb; typedef concurrent_vector<atomic<Foo*>, zero_allocator<atomic<Foo*> > > FooVector; Foo* FetchElement( const FooVector& v, size_t i ) { // i 番目の要素が割り当てられるのを待つ while( i>=v.size() ) std::this_thread::yield(); // i 番目の要素が構築されるのを待つ while( v[i]==NULL ) std::this_thread::yield(); return v[i]; }
一般に、適切なメモリーの一貫性を保証するため、フラグはアトミック型でなければなりません。