1

このコードは大丈夫かどうか疑問に思います:

#include <iostream>
#include <future>
struct Foo
{
    Foo()
        :m_a(0)
    {
    }

    int m_a;
};

int main()
{
    Foo f;
    auto handle =
        std::async( std::launch::async, 
                [](Foo* f) { std::cout << f->m_a << '\n'; } ,
                &f
              );

    handle.get();
}

同期メカニズムで保護する必要があると思いますm_aが、同僚は必要ないと言っています。

編集:私の質問を明確にするために:コンストラクターからの STORE 操作がFoo()、他のスレッドからの LOAD 操作の後に発生することを心配しています。コンパイラがこれらの命令をこの順序で実行するのを妨げているメカニズムがわかりません。

編集:熱心なコンパイラがコンストラクターをインライン化することを決定し、 CALL 操作の後に STORE 操作を遅らせることができると思いますstd::async。この場合、2 番目のスレッドはm_a、メモリにコミットされる前にアクセスできます。

4

1 に答える 1

1

はい、これは正しく同期されています。

の仕様からasync、C++11 30.6.8/5:

の呼び出しは の呼び出しとasync同期しますf

wherefは関数の引数ですasync(例のラムダ)。

の初期化はf.m_a、 への呼び出しの前、asyncつまり非同期関数によるアクセスの前に実行されます。

さらに、

関数 f の完了は、共有状態が準備される前に順序付けられます。

そのため、への呼び出しがget()戻る前、つまりオブジェクトが破棄される前にアクセスが発生する必要があります。

于 2015-01-26T10:38:59.717 に答える