7

このコードはスレッドセーフですか?関数sigにvolatileを含める必要がありますか?(例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;}
};
4

1 に答える 1

8

はい、スレッドセーフですが、成功するまでループでCASを呼び出さないため、名前Lockを変更できます。TryLock従来Lock、操作は取得が成功するまでブロックすることになっています。

に関してvolatileは、 (演算子について)指定するドキュメント:std::atomic=

アトミック変数に値tをアトミックに割り当てます。store(desired)に相当します。

次に約store

void store(Tdesired、memory_order = std :: memory_order_seq_cst);

次に約memory_order = std::memory_order_seq_cst

  • アトミックストアの後で、ライタースレッドの書き込みを並べ替えることはできません
  • リーダースレッドでの読み取りは、アトミックロードの前に並べ替えることはできません。
  • 同期は、std::memory_order_seq_cstとタグ付けされたすべてのアトミック操作間で確立されます。このようなアトミック操作を使用するすべてのスレッドは、同じ順序のメモリアクセスを参照します。

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

実行スレッド内では、すべての揮発性オブジェクトへのアクセス(読み取りと書き込み)が相互に並べ替えられないことが保証されますが、揮発性アクセスはスレッド間の同期を確立しないため、この順序が別のスレッドによって監視されることは保証されません。 。

于 2012-09-09T15:28:29.237 に答える