2016-09-21 5 views
4

how to use std::atomic<>のstd :: btween違い、原子とstd :: mutexの上記の質問で

は、明らかに私たちは、スレッドの安全性を保つためにstd::mutexを使用することができます。私はいつどちらを使うべきかを知りたい。経験則として

classs A 
{ 
    std::atomic<int> x; 

public: 
    A() 
    { 
     x=0; 
    } 

    void Add() 
    { 
     x++; 
    } 

    void Sub() 
    { 
     x--; 
    }  
}; 

std::mutex mtx; 
classs A 
{ 
    int x; 

public: 
    A() 
    { 
     x=0; 
    } 

    void Add() 
    { 
     std::lock_guard<std::mutex> guard(mtx); 
     x++; 
    } 

    void Sub() 
    { 
     std::lock_guard<std::mutex> guard(mtx); 
     x--; 
    }  
}; 
+0

'x'はインスタンス変数です。クラスAのすべてのインスタンスを変更するすべてのスレッドに対して1つの大きなロックを持つ代わりに、クラスメンバをmutexにすることで、きめ細かいロックを得ることができます(もちろん、各Aオブジェクトのサイズが大きくなります)。 –

+0

少なくとも理論的には、C++ UBを避けるためには、読み取り専用アクセッサ関数でもロックを取る必要があります。 (これはstd :: atomicの大きな利点です:読み込み専用アクセスははるかに安いです)。 –

答えて

5

、あなたを与えるであろう(基礎となる専門は、CPUにバスロックのような巧妙なものを使用することができるようになりますPOD型のためstd::atomicを使用パイプラインダンプ以上のオーバーヘッドはありません)、またはスピンロックさえあります。システムによっては、intの場合はすでにである可能性がありますので、std::atomic<int>intに効果的に特化されます。

非PODタイプの場合はstd::mutexを使用してください。ミューテックスを取得することは、バスロックよりも少なくとも1桁遅いことに注意してください。

まだわからない場合は、測定値です。

+0

'int'ロードと' int'ストアは通常アトミック(例えばx86上)ですが、['my_int ++'はマルチコアシステム上で決して原子的ではありません](http://stackoverflow.com/questions/39393850/can- int-for-int-num-for-int-num/39396999#39396999)。私はstd :: atomicプリミティブ型はおそらく有用であるというあなたの全体的なポイントに同意し、他のものはシーンの背後にある効率の悪いロックを行う可能性が高いです。 –

+0

'std :: atomic ' *は16バイトに収まるオブジェクトには役立つかもしれませんが、あなたがやっていることが分かっていて、x86- 64 'lock cmpxchg16b'とし、' -mcx16'でビルドします(cmpxchg16bは拡張機能ですが、残念ながらベースラインx86-64には含まれていませんでした。 ://stackoverflow.com/questions/38984153/implement-aba-counter-with-c11-cas)オブジェクトの2つのポインタのサイズの比較とスワップについて。 –

関連する問題