高度な表現方法: 要素での待機

スレッドは、別のスレッドによって非同期に追加されている要素 v[i] を待たなければならないことがあります。次のような表現で待機することができます。

  1. i<v.size() まで待機する。この後、v[i] は割り当てられますが、おそらく構築されません。

  2. v[i] が構築されるのを待つ。

ステップ 2 を行う最適な方法は、要素のアトミックフラグがゼロ以外になるのを待つことです。要素全体がフラグの場合もあります。要素が構築されるまでフラグがゼロであることを保証するには、次の操作を行います。

次のサンプルでは、ベクトル要素がアトミックポインターです。ベクトルに追加されるポインターはゼロ以外であると仮定しているため、フラグはポインターそのものです。

#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];
}

一般に、適切なメモリーの一貫性を保証するため、フラグはアトミック型でなければなりません。

関連情報