6

ローカル配列とスレッドとのやりとりのためのC++ 98とC++ 11のメモリモデルは何ですか?C++ローカル変数とスレッド(thread_localではない)

私はグローバル変数と静的変数に関連するC++ 11 thread_localキーワードを参照ないよ。

代わりに、コンパイル時に割り当てられた配列のスレッドの動作が保証されているかどうかを調べたいと思います。コンパイル時には、私は "int array [100]"を意味します。これはnew []キーワードを使った割り当てとは異なります。私はの静的な変数を意味しません。

たとえば、のは、私は、次の構造体/クラスを持っているとしましょう:

struct xyz { int array[100]; }; 

と、次の関数:

void fn(int x) { 
    xyz dog; 
    for(int i=0; i<100; ++i) { dog.array[i] = x; } 
    // do something else with dog.array, eg. call another function with dog as parameter 
    } 

は、複数のスレッドからFN()を呼び出すことは安全ですか? C++メモリモデルは、すべてのローカル非静的変数と配列がスタックに割り当てられ、各スレッドに独自のスタックが割り当てられているようです。これは本当ですか(つまり、これは公式に標準の一部ですか)?

答えて

8

このような変数はスタックに割り当てられ、各スレッドには独自のスタックがあるため、ローカル配列を使用することは完全に安全です。それらは、例えば、ローカルint s。

+0

ありがとうございました。これは明示的にC++ 11標準で書かれていますか? – mtall

+0

@mtall:間接的に。関数本体のすべての非静的変数は、関数スコープの一部であり、自動保存期間を持ちます。これは 'std :: thread :: thread(F &&、Args && ...)'によって呼び出される関数にも当てはまります。すべてを一緒に困惑させたい場合は、4つのセクションを読まなければなりません。 – Zeta

+0

最後に、 'fn'を呼び出すたびに' xyz'のインスタンスが作成されます。したがって、2つのスレッドが同時に 'fn'を呼び出すと、両方のスレッドはスレッドセーフである' xyz'の独自のインスタンスを作成して変更します。 – TianyuZhu

2

C++ 98はスレッドについて何も言わなかった。 C++ 98に書き込まれているがスレッドを使用するプログラムは、C++ 98で定義された意味を持ちません。もちろん、スレッド拡張でスレッドに安定したプライベートなローカル変数を提供することは賢明です。通常はそうしています。しかし、vforkによって作成されたプロセス(例えば、vforkvは、アドレス空間を複製しないことを意味するため、一部のUnixシステムでは親と子が同じスタックフレームで実行されるプロセス) vforkは、新しいプロセスを別の機能にリダイレクトしません。

C++ 11では、スレッドのサポートがあります。独立したC++ 11スレッドの別個のアクティベーションチェーン内のローカル変数は干渉しません。しかし、あなたが言語の外に出てvforkまたはそれに似ているものを外したら、すべてのベットは前と同じようにオフになります。

しかし、ここに何かがあります。 C++にはクロージャがあります。 2つのスレッドがどちらも同じクロージャを呼び出すとどうなりますか?次に、同じローカル変数を共有する2つのスレッドがあります。クロージャーはオブジェクトのようなもので、キャプチャされたローカル変数はメンバに似ています。 2つ以上のスレッドが同じクロージャを呼び出す場合、メンバ(つまり、キャプチャされたレキシカル変数)が共有される事実上のマルチスレッドオブジェクトが存在します。

スレッドは、ローカル変数のアドレスを別のスレッドに渡して共有することもできます。

+0

値によるキャプチャはスレッド間で何も共有しないため、参照によるキャプチャと値によるキャプチャを区別します。 – Zeta

+0

'vfork()'は、子プロセスが自身の上に別の実行可能イメージを終了するかロードするまで親プロセスをブロックし、子プロセスが他の関数を呼び出したり現在のプロセスから戻ると、親スタックを破壊し、私は 'vfork()'で有用なスレッディングをどのように実装できるのか分かりません。 –

+0

@HristoIlievあなたが見ているシステムではそうかもしれませんが、Unixではそうでないかもしれません。私はここで親をブロックすることについて何も見ません:http://pubs.opengroup.org/onlinepubs/007908775/xsh/vfork.html – Kaz

関連する問題