2016-08-09 17 views
3

ダミーだと思うかもしれませんが、混乱していると思いますが、これを見てみると同じ状況に見える場合はquestionです私は自分のmapを静的なものにする必要があるので、別のthreadsで作成されるすべてのインスタンスに共通であり、私のマップ上で動作する関数を同期したいので、私はstd::mutexを私のクラスのstaticこの場合、mutex自体を取得してロックする競合状態が発生するでしょうか?静的ミューテックスのためにレースの条件を作成すると、我々はmutexstd :: mutexを静的にすると、mutex自体の競合条件が生成される

+4

明らかに、最初のミューテックス – Praetorian

+2

を保護するためには2番目のミューテックスを使用する必要があります(私は冗談ですが、データ競合の影響を受けやすいミューテックスは無意味です) – Praetorian

+0

@Praetorian。あなたの最初のコメントに、私はWTFを入力しようとしていました...ハハ – WhiZTiM

答えて

6

を使用してstatic map上の機能を同期させることができる任意のより良い方法があるにはありません、Mutexレースに対して脆弱ではありません 自体

std::mutexを作るん-条件。そして、それをstaticとして初期化する場合、あなたは安全です。

$6.7: 4:静的記憶期間を持つブロックスコープ変数の動的な初期化([basic.stc.static])またはスレッドストレージ 持続時間は、([basic.stc.thread])最初の時間制御 を行いますその宣言を通過する。そのような変数は、その初期化の完了時に初期化されたと考えられます( )。 初期化が例外をスローすることによって終了する場合、初期化は が完了していないため、次回にコントロールが 宣言を入力したときに再試行されます。コントロールは、変数が初期化され、同時に ながら宣言を入力した場合、同時実行は、初期化の完了を を待たなければなら


あなたは言った:

iがstd::mutexなどを行うことを考えました指定されたリンクの答えとして が提案されたような、私のクラスの静的です。

また、staticのクラスメンバー変数も保護しようとしていますか?それ以外の場合は、mutableメンバーにしてください。 mapがグローバルに初期化されると言ったという事実はstaticです。メンバ変数としてのmutexはスイートに従うので、大丈夫です。今

class Map{ 
public: 
    Map(...){} 

    std::size_t size() const{ 
     std::lock_guard<std::mutex> lck(m_m); 
     return m_size; 
    } 

    iterator add(....) { 
     std::lock_guard<std::mutex> lck(m_m); 
     .... 
     return your_iterator; 
    } 

    ...etc 

private: 
    mutable std::mutex m_m; //FREE ADVICE: Use a std::recursive_mutex instead 
    ...others 
}; 

//Somewhere at global scope: 

Map mp(... ...); 

// NOTES 
// 1. `mp` will be initialized in a thread safe way by the runtime. 
// 2. Since you've protected all Read or Write member functions of the class `Map`, 
// you are safe to call it from any function and from any thread 
2

ミューテックス(および他の同期プリミティブ)は、オペレーティングシステムからのサポートを使用して実装されています。それが彼らの仕事を行う唯一の方法です。

このジョブを実行する能力の直接コロラドは、自身が競合状態になりにくいことです。— mutexのロックとロック解除の操作はアトミックです。

そうでなければ、あまり役に立ちません。ミューテックスを使うたびに、別のミューテックスでそのミューテックスを保護してから、そのミューテックスを別のミューテックスで保護しなければならなくなります。無限のミューテックスがあるまで、まったく。 :)

std::mutex静止保存期間を持つオブジェクトは、これを変更しません。おそらく、あなたは関数 - staticの変数を考えていたでしょう(競合状態に耐えられていないと仮定すると、それらは異なるスレッドによって同時にアクセスされる可能性があるので同期されなければなりませんが、理想的には、機能をリエントラントにしない)。

関連する問題