web-dev-qa-db-ja.com

scoped_lockはreadedモードでshared_mutexをロックできますか?

C++ 17では、_std::shared_mutex_と_std::scoped_lock_の両方が導入されました。私の問題は、_scoped_lock_が、共有(リーダー)モードではなく、引数として渡されたときに、共有ミューテックスを常に排他(ライター)モードでロックするように見えることです。私のアプリでは、オブジェクトdstをオブジェクトsrcのデータで更新する必要があります。 src共有およびdst排他をロックしたい。残念ながら、srcdstが切り替えられた別の更新メソッドの呼び出しが同時に発生すると、デッドロックが発生する可能性があります。そこで、_std::scoped_lock_の派手なデッドロック回避メカニズムを使用したいと思います。

_scoped_lock_を使用してsrcdstの両方を排他モードでロックすることもできますが、その不必要に厳密なロックでは、他の場所でパフォーマンスが低下します。ただし、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???
}
_

このような(共有)ロックガードを別の(デッドロック回避)ロックガード内で使用しても安全ですか?

15
Kai Petzke

Mutex:共有リソースにスレッドセーフを追加します
Lock:RAII(および場合によっては追加機能)をmutexに追加します

さまざまなロックを使用すると、さまざまな方法でミューテックスをロックできます。

  • unique_lock:リソースへの排他的アクセス(書き込み用)
  • shared_lock:リソースへの共有アクセス(同時読み取り用)
  • scoped_lock:unique_lockと同じですが、機能が少なくなっています

scoped_lockは、構築時にロックされ、破棄されるとロック解除されるベアボーン専用ロックです。 unique_lockshared_lockはそれぞれ排他ロックと共有ロックであり、デフォルトのコンストラクタとデストラクタでロックおよびロック解除されます。ただし、追加の機能も提供します。たとえば、 運を試してみてください 、または破壊される前にロックを解除できます。

したがって、一般的な使用例は、共有アクセスにshared_lockを使用し(複数のスレッドが同じリソースを読み取る場合)、排他的アクセスにunique_lockまたはscoped_lockを使用することです( unique_lockの追加機能が必要かどうか)。

0
pooya13