2017-07-05 5 views
0

は、私が持っている:他のスレッドスタック変数へのアクセスはどのようにしてС++で動作しますか?例えば

int main() 
{ 
    int i = 0; 
    std::thread t([&] { 
     for (int c = 0; c < 100; ++c) 
      ++i; 
    }); 

    t.join(); 

    return 0; 
} 

スレッドt変更変数i値を。 私は、OSが現在のスレッドを変更すると、古いスレッドスタックを保存して新しいスレッドスタックをコピーする必要があると思います。

オペレーションシステムは、iにどのように正しくアクセスできますか? オペレーティングシステムレベルでどのように動作するのか説明がありますか?ラムダ関数のローカル変数のキャプチャとどのようにスレッドとそのスタックが動作:あなたの例のコードで遊んで二つの別々のものがあります

int main() 
{ 
    int* i = new int; 
    std::thread t([&] { 
     for (int c = 0; c < 100; ++c) 
      ++(*i); 
    }); 

    t.join(); 

    return 0; 
} 
+0

参考資料:http://en.cppreference.com/w/cpp/language/lambda(ヒント:「i」は参照によって取得されます) –

+7

参照の仕組みを知っていますか?スレッドはプロセスのメモリを共有していることは知っていますか? –

+0

スタックをデプロイするときにOSが実際に変数を移動しないとします。それは参照を使用していますか?または、現在のスレッドのスタックを指しているかもしれませんか? – voltento

答えて

1

は、私のようなものを使用する場合、それはより生産行います。

ラムダ関数が作成されたときのローカル変数の取得は、ラムダが同じスレッドか別のスレッドかにかかわらず同じ方法で動作します。基本的に変数への参照はラムダに渡されます。 詳細については、How are C++11 lambdas represented and passed?を参照してください。

スレッドは、Margaret Bloomによってコメントされているように、プロセスのアドレス空間を共有します。彼らは同じメモリ(グローバル変数を含む)を読み込んで変更するためのアクセス権を与えました。各スレッドには異なるスタック領域が割り当てられていますが、スタックはすべてプロセスのアドレス空間にあり、すべてのスレッドは他のスレッドのスタック領域にアクセスできます。したがって、スレッドが別のスレッドスタック内の変数へのポインタまたは参照を持つ場合、そのスレッドはそれを読み込んで変更することができます。

これらの2つの要素を一緒に追加すると、サンプルコードが機能します。

間接参照のレベルが1つ少なくなるため、コードの最初のバージョンがおそらくわずかに効率的です。

関連する問題