6

ローカル配列およびスレッドとの相互作用のための C++98 および C++11 メモリ モデルは何ですか?

グローバル変数と静的変数に関連する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++ のメモリ モデルは、すべてのローカルの非静的変数と配列がスタックに割り当てられ、各スレッドが独自のスタックを持っているようです。これは本当ですか (つまり、これは公式に標準の一部ですか)?

4

2 に答える 2

9

このような変数はスタックに割り当てられ、各スレッドには独自のスタックがあるため、ローカル配列を使用しても完全に安全です。それらは local などと違いはありませんint

于 2013-03-05T07:10:17.020 に答える
3

C++98はスレッドについて何も言いませんでした。それ以外の場合はC++98で記述されているが、スレッドを使用するプログラムには、C++98で定義されている意味はありません。もちろん、スレッド拡張機能が安定したプライベートローカル変数をスレッドに提供することは賢明であり、通常はそうします。ただし、これが当てはまらないスレッドが存在する可能性があります。たとえばvfork、一部のUnixシステムで作成されたプロセスでは、親と子が同じスタックフレームで実行されます。これは、vinvforkがアドレス空間のクローンを作成しないことを意味vforkし、新しいプロセスを別の関数にリダイレクトします。

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

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

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

于 2013-03-05T07:21:23.380 に答える