В С++ 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???
}
Безопасно ли использовать (совместно используемый) защитный кожух, как этот, внутри другого защитного кожуха?