В С++ 17 введены как std::shared_mutex
и std::scoped_lock
. Моя проблема сейчас в том, что кажется, что scoped_lock
блокирует общий мьютекс всегда в режиме монопольного scoped_lock
(записи), когда он передается в качестве аргумента, а не в режиме общего доступа (чтения). В моем приложении мне нужно обновить объект dst
с данными из объекта src
. Я хочу заблокировать src
shared и dst
exclusive. К сожалению, это может привести к взаимоблокировке, если одновременно происходит вызов другого метода обновления с переключенными src
и dst
. Поэтому я хотел бы использовать причудливые механизмы предотвращения тупиковых ситуаций в std::scoped_lock
.
Я мог бы использовать scoped_lock
для блокировки как src
и dst
в монопольном режиме, но эта неоправданно строгая блокировка снижает производительность в других местах. Тем не менее, кажется, что можно обернуть src
shared_mutex
в std::shared_lock
и использовать его с scoped_lock
: когда scoped_lock
во время действия блокировки вызывает try_lock()
для shared_lock
, последний на самом деле вызовет try_shared_lock()
для src
shared_mutex
, и это то, что мне нужно.
Так что мой код выглядит так просто:
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???
}
Безопасно ли использовать (совместно используемый) защитный кожух, как этот, внутри другого защитного кожуха?