2012-09-09 5 views
7

このコードはスレッドセーフですか?私は関数sigに揮発性があるべきですか? (例:void Unlock() volatile {v=0;})どうすればこのスレッドセーフができますか?この単純(アトミック)ロックスレッドは安全ですか?

class SimpleLock { 
    std::atomic<int> v; 
public: 
    bool try_lock() { int z=0; return v.compare_exchange_strong(z, 1); } 
    void lock() { while(try_lock()==false) std::this_thread::yield(); } 
    void unlock() {v=0;} 
}; 
+0

これはおもちゃのコードなので、実際のアプリケーションでは使用しないでください。適切なロックと比較してパフォーマンスはひどくなります。 (単なる一例として、他のスレッドが得られず、 'lock'を呼び出すスレッドがロックを保持するスレッドと同じ物理的なコアで実行されている場合) –

答えて

8

それが成功するまで、あなたがループ内でCASを呼び出していませんので、あなたがTryLockLockの名前を変更する可能性があるがはい、それは、スレッドセーフです。伝統的にLock操作は、取得が成功するまでブロックされると考えられます。 volatileに関して

std::atomicthe docsは(=オペレータについて)を指定:

アトミックアトミック変数に値tを割り当てます。店舗に相当する(希望)。そして

store

ボイドストア(T、所望の、memory_order = STD :: memory_order_seq_cst)。

その後についてmemory_order = std::memory_order_seq_cst

  • いいえライター・スレッドに書き込みはありませんが、読者のスレッドに読み込む
  • がアトミック負荷の前に並べ替えることができ、原子 ストアの後に並べ替えることができます。
  • 同期は、std :: memory_order_seq_cstタグのすべてのアトミック操作間で確立されます。そのような原子番号 操作を使用するすべてのスレッドは、同じメモリアクセス順序を参照します。

だから、volatileは必要ありません。また、volatileは(実際には、volatileはC++でほとんど役に立たない)上記のものよりも弱い保証があります。

実行のスレッド内では、すべての 揮発性のオブジェクトができないことが保証されているに(読み取りおよび書き込み)アクセス揮発性アクセスはスレッド間で の同期を確立しないため、 otherに対して再順序付けされますが、この順序は別の スレッドによって観測されることが保証されません。

+0

正しい。今、 'bool TryLock()volatile'でなければならないのかどうかは分かりますか? –

+0

標準ライブラリでこのロックを使いたい場合は、 'bool try_lock()'と 'void unlock()'と呼ぶ方が良いでしょう。 – kennytm

+0

@ acidzombie24:私の編集を参照してください。 – Tudor

関連する問題