2016-04-04 1 views
4

リーダー/ライターのシナリオでstd :: shared_ptrを使用したいと考えています。あるスレッドは常に新しい情報を受け取り、最新のデータへのスマートなポインタを保持します。私の遅い計算を実行する時が来たら、私はすべてのデータにスマートなポインタをとり、一貫性のあるデータを確認しています。下の例では、aとbを使用すると、それらが一緒に属していることが分かります。1つのリーダーと1つのライタースレッドを持つときにstd :: atomic_を使用する必要がありますか?

ここでatomic_loadとatomic_storeを使用する必要があるかどうかわかりません。一貫性があり有効である限り、私が見ているFooのバージョンはあまり気にしません。

このコードを2つの異なるスレッドから処理するには、ここで私のスマートポインタにアトミックを使用する必要がありますか?

おかげで、

ポール

#include <iostream> 
#include <memory> 


class Foo{ 
public: 
    int a; 
    int b; 
}; 

class MyClass{ 
public: 
    std::shared_ptr <Foo> lastValue; 
    void realTimeUpdate (Foo* latest) { //takes ownership of Foo 
     lastValue=std::shared_ptr <Foo> (latest); //Is this OK to do without using std::atomic_? 
    }; 

    void doSlowCalcFromAnotherThread() { 
     //take a reference to all input data 
     std::shared_ptr <Foo> stableValue=lastValue; //Is this OK to do without using std::atomic_ 
     //display a and b guaranteed that they come from the same message 
     std::cout<<"a: "<<stableValue->a<<std::endl; 
     std::cout<<"b: "<<stableValue->b<<std::endl; 
    }; 
}; 
+0

おそらく 'std :: mutex'を使ってポインタへのアクセスを保護し、それを1日と呼びます。 'std :: shared_ptr'への代入はアトミックではありません。 –

答えて

1

はい、二つのスレッド間のすべての通信は、何らかの方法で保護されなければなりません。この場合の問題は、=、両方のスレッドが、それは

+0

私はhttp://en.cppreference.com/w/cpp/memory/shared_ptr/atomicのようなものを使うことを望んでいた –

+0

もしあなたがC++ 11コンパイラを持っていれば、あなたはそれを行うことができます!そして、すべてが良いだろう – vu1p3n0x

2
  1. のshared_ptr ::オペレータにアクセスしている場合std::shared_ptr<>::operator=が未定義の動作を呼び出すことができるので、アトミックであることが保証とされていないことであるデフォルトではアトミックではありません。
  2. shared_ptrはTriviallyCopyableではないため、std :: atomicのテンプレートパラメータにすることはできません。

他の方法で同期する必要があります。 std :: mutex経由で。

2

はい、std::shared_ptr引数の場合、とstd::atomic_store()には、memoryヘッダーがオーバーロードされていなければなりません。それ以外の場合は、コードにデータ競合があります。 (私はあなたの質問のタグに従ってC++ 11に準拠したコンパイラがあると仮定します)。

+0

ありがとう。残念ながら、gcc 4.9.2はstd :: atomic_loadを実装せず、std :: shared_ptrのためにストアするので、私はmutexに固執する必要があります。 C++ 17にはstd :: atomic_shared_ptrが含まれていますが、これらの場合には動作するはずですが、それが利用可能になるまでにはしばらく時間がかかります。 –

関連する問題