複数のスレッドからの追加、削除、反復子をサポートするスレッドセーフC ++ std :: set
-
05-07-2019 - |
質問
JavaのCopyOnWriteSetに似たものを探しています。複数のスレッド。
解決
私が知っているものはありません。最も近いのは、 concurrent_unordered_map
STLコンテナは、複数のスレッドからの同時読み取りアクセスを許可します。 同時変更を行わない限り。多くの場合、追加/削除中に繰り返す必要はありません。
単純なラッパークラスの提供に関するガイダンスは正解です。以下のコードスニペットのようなものから始めて、実際に同時アクセスが必要なメソッドを保護し、ベースstd :: set so folksへの「安全でない」アクセスを提供します安全でない他の方法を選択できます。必要に応じて、イテレータを取得して戻すことへのアクセスも保護できますが、これは注意が必要です(独自のロックフリーセットまたは完全に同期されたセットを作成するよりも、それほど複雑ではありません)。
並列パターンライブラリを使用しているため、VS2010 beta boost :: mutexのcritical_sectionを使用していますが、どのように選択しても、lock_guardを使用するRAIIパターンはほとんど必要です:
template <class T>
class synchronized_set
{
//boost::mutex is good here too
critical_section cs;
public:
typedef set<T> std_set_type;
set<T> unsafe_set;
bool try_insert(...)
{
//boost has a lock_guard
lock_guard<critical_section> guard(cs);
}
};
他のヒント
同時アクセスを保護するために共有ミューテックスを使用するだけではどうですか?必ずmuiiをロックおよびロック解除するためにRAIIを使用してください。
{
Mutex::Lock lock(mutex);
// std::set manipulation goes here
}
Mutex :: Lockは、コンストラクターでミューテックスをロックし、デストラクタでロック解除するクラスです。ミューテックスは、すべてのスレッドで共有されるミューテックスオブジェクトです。 Mutexは、使用している特定のOSプリミティブを隠すラッパークラスです。
並行性と集合の振る舞いは直交する概念であると常に考えてきたので、それらを別々のクラスに入れる方が良いです。私の経験では、自分自身でスレッドセーフにしようとするクラスは、あまり柔軟ではないか、それほど便利ではありません。
不変式は多くの場合データ構造に対して複数の操作を必要とするため、内部ロックは必要ありません。内部ロックは、同時に発生するステップのみを防止しますが、インターリーブ。
また、必要なすべてのスレッドセーフコンテナを備えたACEライブラリを確認することもできます。
考えられるのは、並列化にOpenMPを使用し、stdからsetクラスを派生させ、#pragma omp criticalを使用してその重要な操作を宣言する各重要なset操作をシェルで囲むことです。
QtのQSetクラスは、暗黙的な共有(書き込み時のセマンティクスのコピー)と同様のメソッドをstd :: setで使用します。実装を確認できます。Qtはlgplです。
スレッドセーフとコピーオンライトセマンティクスは同じものではありません。言われていること...
実際にコピーオンライトセマンティクスを使用している場合、Adobeソースライブラリには これらのセマンティクスをインスタンス化するものに追加するcopy_on_write
テンプレート。