2016-12-03 12 views
0

常に読み書き可能(lockfree)な単一の値を格納するためのC++コンテナ(シングルライター、多くのリーダー)がありますか?古いバージョンを読むのは大丈夫です。単一オブジェクトのスレッドセーフコンテナ(C++)

私はそのようなことを考え:私は考え

template <class T> 
class Container { 
    bool active = 0; 
    T object[2]; 
public: 
    void writeData(T t) 
    { 
     object[!active] = t; 
     active = !active; 
    } 
    T readData() 
    { 
     return object[active]; 
    } 
}; 

一つの問題:アクティブな原因の

Read thread reads active = 0 
Write thread happens (active = 1) 
another Write thread starts and writes to 0 
Read thread reads the data which is currently written to 

はアトミックではありませんが、それはブール値であり、唯一の1つの書き込みスレッドが起こるので、一度に両方の可能な値が許容​​されます。

+0

コンパイラがコードを最適化するときに何が起こるかを検討する必要があります。他のスレッドで更新されている可能性がある場合、値を再読み込みする必要があることをコンパイラが認識しないため、コードを省略することができます。コンパイラが不要な読み込み(または書き込み)を削除するよう最適化すると、更新された値が決して表示されないことがあります。 –

答えて

0

ない完全なソリューションが、これを行うことができる方法のアイデア:

を保存したい、その値を仮定は、非プリミティブ型は、(そうでない場合は、単にhttp://en.cppreference.com/w/cpp/atomic/atomicを参照してください、atomicを使用)、あなたが何ができるか使用ですあなたのオブジェクトへの中央ポインタとしてatomic<Container*> current_container;のようなものです。そして、あなたのwriterの各アップデートでは、完全に新しいデータを持つContainerオブジェクトを更新し、完了したらcurrent_containerが新しいオブジェクトを指すように設定します。このアプローチにはいくつかの注意点があることを

注:ライターで

  • は、読者の一部はまだそれを使用している可能性があるため、すぐに交換した後Containerの古いインスタンスを削除することはできません。コンテナが動的に割り当てられる場合、これは扱いにくいかもしれません。あなたはそれに値を変更する手段として

  • http://en.cppreference.com/w/cpp/memory/shared_ptr/atomicを参照)current_containeratomic_exchageためstd::shared_ptrを使用する場合があります完全に更新毎Containerの新しいバージョンを準備するためにライターが必要になります。このアプローチ - これはコストがかかる可能性がContainerが大きい場合にはそのコピーが高価である場合

0

私はすぐに使用できる実装を知りません。しかし、C++標準にそのような機能を持たせるための努力があります。 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0561r3.html

論文では、完全なスレッドセーフと埋め戻しのために、解決すべきかなり複雑な問題があることを示しています。いずれにしても、この文書の仕様は正しい実装の作成に役立つはずです。

関連する問題