web-dev-qa-db-ja.com

C ++静的メンバー変数の初期化はスレッドセーフですか?

以下のリソースによると、C++(特にVisual C++)では、スコープ付き静的変数の初期化はスレッドセーフではありません。ただし、グローバル静的変数は安全です。

ミューテックスなしのスレッドセーフな静的変数?

http://blogs.msdn.com/oldnewthing/archive/2004/03/08/85901.aspx

それで、静的メンバー変数を持つ次のコードはスレッドセーフですか?

class TestClass
{
public:
   static MyClass m_instance;
}

Myclass TestClass::m_instance;

前もって感謝します!

24
Varuna

それは、スコープ対グローバルではなく、関数スコープの静的変数対他のすべての種類の静的変数の問題です。

関数スコープ以外の静的変数はすべてmain()の前に作成されますが、アクティブなスレッドは1つだけです。関数スコープの静的変数は、それらを含む関数が最初に呼び出されたときに作成されます。この標準は、関数が複数のスレッドで呼び出されたときに関数レベルの統計がどのように構築されるかについては言及していません。ただし、私が使用したすべての実装では、コンストラクターの周りのロック(2回チェックされたフラグ付き)を使用して、スレッドセーフを保証しています。

35
Marcelo Cantos

はい(*)。グローバルスタティックが初期化されると、スレッドは1つだけになり、すべてのコンストラクターが呼び出されます。ただし、これは関数の統計には当てはまりません。

(*)いくつかのコンストラクターでスレッドを作成し、これらのスレッドでいくつかの初期化ステージをスケジュールすることにより、グローバル統計をスレッドセーフではなくする可能性があります。この場合、通常のスレッドセーフルールが適用されます。

3
Rom