2016-11-11 9 views
2

std::vectorthread_localと宣言する利点はありますか?いつ誰かがthread_localとしてstd :: vectorを定義しますか?

static unique_ptr<std::vector<ObjectA>> vecVariable; 

よう thread_localがpop_back()と同期erase()などの事業を行わないようstd::vectorを宣言するように。

コンテナを修正する一つのスレッドがある場合は、すべてのSTLコンテナのように、そこに同じコンテナを読んだり、書いて何の同時実行スレッドはならないので、私は、マルチスレッド/並行環境でvectorオブジェクトにerase()pop_back()を行うことはできません。

ベクトルをthread_localと宣言しても、コードの1つがクラッシュしています。私はロックの下でこれらの操作を行う必要があるかもしれないと理解していますが、私はちょうど誰かがとしてstd::vectorを定義するのを理解しようとしていますか?

+0

同時に、変数はすべてthread_localとして定義されます。各スレッドはそれぞれ独自のインスタンスを持ちます。 – davmac

答えて

4

thread_localは、オブジェクトにのスレッド記憶域を持ちます。これは、各スレッドがオブジェクトの別々のインスタンスを持つことを意味します。どのような方法でも、オブジェクトのスレッドセーフティには影響しません。そうするべきだと考えるように思われます。

vector変数、またはその他の変数thread_localを宣言します。各スレッドに変数のインスタンスが必要な場合は、 1つのオブジェクトに同時にアクセスできるようにするには、thread_localを宣言するのではなく、スレッドセーフなデータ型または適切な同期プリミティブ(たとえば、std::mutexのロックとロック解除による)を使用することです。

+0

@GillBates各スレッドは、他の方法で参照を取得できる場合は、他のスレッドに属するコピーにアクセスできます。名前が異なるスレッドの異なるオブジェクトを参照しているということは、スレッドの安全を意味するものではありません。 – davmac

+0

もちろん、アドレスの受け渡しやグローバル参照が可能です。私は名前と名前だけを使用する場合について話していました。 –

+0

私が言ったように、このベクトルの要素に名前でアクセスするとき、最初にスレッドの安全性に気を付ける必要はありません。 'ベクトル[0]'。キーワードそのものは同期化を行いませんが、スレッドが他のスレッドに依存してこのコンテナを生成または変更しない場合、スレッド間のデータ競合を回避します。 –

5

thread_localは、同期化に使用することはできません。これは、記憶域期間指定子(http://en.cppreference.com/w/cpp/language/storage_duration

として意図され、この例を見てみましょう:

#include <iostream> 
#include <vector> 
#include <thread> 

thread_local std::vector<int> v; 

void func() 
{ 
    v.push_back(5); 
    std::cout<< "t: "<< v.size() << std::endl; 
} 

int main() 
{ 
    v.push_back(3); 
    v.push_back(5); 
    std::thread t1(func); 
    std::thread t2(func); 
    std::cout<< "m: "<< v.size() << std::endl; 
    t1.join(); 
    t2.join(); 
} 

出力:

m: 2 
t: 1 
t: 1 

thread_localは、スレッドごとに異なるベクトルを作成することです。この例では、メインスレッドのvには2つの要素があり、その他のスレッドのベクトルvにはそれぞれ1つの要素しかないことがわかります。

何が起こるかは、新しいスレッドが作成されると、プログラムはこのスレッドの新しいベクトルを作成するだけです。スレッドは終了時にも破棄されます。