私はTBB フォーラムでこの質問をしましたが、ここの誰かが追加の考えを持っていることを願っています. 発生している問題をデバッグしていたところ、 の奇妙な動作に気付きましたtbb::concurrent_vector
。
push_back()
肝心なのは、呼び出しが実際に完了した後、size()
の にconcurrent_vector
はこれが反映されないということです。capacity()
と をキャプチャするとsize()
、実際の要素数ではなく容量が返さsize() == capacity() => true
れると思われるため、容量に関連するように絞り込みました。size()
この問題を再現する簡単なプログラムを作成しました。この問題は、ベクターが空のときに最も頻繁にトリガーされます。簡単にするために、このプログラムは、呼び出しが返さsize() != 0
れた直後に単純にアサートします。push_back()
これが予想される動作なのか、それともバグなのか、誰かが教えてくれることを願っています。
#include <boost/thread.hpp>
#include <tbb/concurrent_vector.h>
typedef tbb::concurrent_vector<int> vec_type;
void invokePushBack(vec_type * vec)
{
for(int i = 0 ; i < 10 ; ++i)
{
vec_type::iterator it = vec->push_back(1);
assert(vec->size() != 0);
}
}
int main()
{
// note: the race condition doesn't always trigger,
// so we loop until it does.
while(true)
{
vec_type vec;
boost::thread_group tg;
for(int i = 0 ; i < 5 ; ++i)
tg.create_thread(boost::bind(invokePushBack, &vec));
tg.join_all();
}
}
彼らのリファレンスマニュアルによると:
push_back() "ベクターの末尾に値のコピーを追加します。"
と
size() は、「ベクター内の要素の数。結果には、いずれかの成長メソッド (5.6.3) への同時呼び出しによって割り当てられているが、まだ構築中の要素が含まれる場合があります。」
これに基づいて、少なくとも一度のリターンを反映するsize()
必要があると思います。push_back()
push_back()