Верен ли мой путь?
Подумайте, что произойдет, если код между блокировкой мьютекса и разблокировкой вызовет исключение:
void write() {
mut_.lock();
// <-- exception is thrown here
mut_.unlock();
}
Тогда мьютекс остается заблокированным.
Есть ли преимущества одного над другим?
Да, unique_lock<>
следует за идиомой RAII , и поэтому разблокировка мьютекса обрабатывается автоматически (т. е. его деструктором) в случае исключения:
void write() {
unique_lock<shared_mutex> lk(mut_);
// <-- exception is thrown
}
В случае исключения после создания объекта unique_lock<shared_mutex>
- lk
- его вызывается деструктор, и затем он разблокирует связанный мьютекс, если он был заблокирован (помните, что std::unique_lock
, в отличие от std::lock_guard
, не всегда владеет блокировкой на связанном мьютексе - см. std::defer_lock
и std::unique_lock::unlock()
).
Подводя итог, с помощью lock_guard
/ unique_lock
/ shared_lock
не требуется никакой специальной обработки с вашей стороны в случае исключений или при выходе из функции-члена из разных путей выполнения.