C++ 17では、_std::shared_mutex
_と_std::scoped_lock
_の両方が導入されました。私の問題は、_scoped_lock
_が、共有(リーダー)モードではなく、引数として渡されたときに、共有ミューテックスを常に排他(ライター)モードでロックするように見えることです。私のアプリでは、オブジェクトdst
をオブジェクトsrc
のデータで更新する必要があります。 src
共有およびdst
排他をロックしたい。残念ながら、src
とdst
が切り替えられた別の更新メソッドの呼び出しが同時に発生すると、デッドロックが発生する可能性があります。そこで、_std::scoped_lock
_の派手なデッドロック回避メカニズムを使用したいと思います。
_scoped_lock
_を使用してsrc
とdst
の両方を排他モードでロックすることもできますが、その不必要に厳密なロックでは、他の場所でパフォーマンスが低下します。ただし、src
の_shared_mutex
_を_std::shared_lock
_にラップし、それを_scoped_lock
_で使用することは可能であるようです。ロック中に_scoped_lock
_の場合アクションは_shared_lock
_でtry_lock()
を呼び出し、後者は実際にはsrc
の_shared_mutex
_でtry_shared_lock()
を呼び出します。これが私に必要なことです。
したがって、私のコードは次のように単純に見えます。
_struct data {
mutable std::shared_mutex mutex;
// actual data follows
};
void update(const data& src, data& dst)
{
std::shared_lock slock(src.mutex, std::defer_lock);
std::scoped_lock lockall(slock, dst.mutex);
// now can safely update dst with src???
}
_
このような(共有)ロックガードを別の(デッドロック回避)ロックガード内で使用しても安全ですか?
Mutex:共有リソースにスレッドセーフを追加します
Lock:RAII(および場合によっては追加機能)をmutexに追加します
さまざまなロックを使用すると、さまざまな方法でミューテックスをロックできます。
scoped_lock
は、構築時にロックされ、破棄されるとロック解除されるベアボーン専用ロックです。 unique_lock
とshared_lock
はそれぞれ排他ロックと共有ロックであり、デフォルトのコンストラクタとデストラクタでロックおよびロック解除されます。ただし、追加の機能も提供します。たとえば、 運を試してみてください 、または破壊される前にロックを解除できます。
したがって、一般的な使用例は、共有アクセスにshared_lock
を使用し(複数のスレッドが同じリソースを読み取る場合)、排他的アクセスにunique_lock
またはscoped_lock
を使用することです( unique_lock
の追加機能が必要かどうか)。