Ответ 1
Почему это предпочтительнее для функций-членов: lock() и:: unlock()?
По той же причине, почему RAII-идиома стала популярной вообще (это всего лишь один из ее бесчисленных экземпляров): потому что вы можете быть уверены, что не оставите текущей области без разблокировки мьютекса.
Обратите внимание, что это не просто забыть вызвать unlock()
: может произойти исключение, если ваш мьютекс заблокирован, а ваш вызов unlock()
никогда не будет достигнут, даже если у вас нет return
между вызовом lock()
и вашим вызовом unlock()
.
m.lock() // m is a mutex
// ...
foo(); // If this throws, your mutex won't get unlocked
// ...
m.unlock()
В этом случае деструктор вашего защитника scoped_lock
будет вызван во время разматывания стека, убедившись, что связанный мьютекс всегда освобождается.
{
boost::scoped_lock lock(m); // m is a mutex
// ...
foo(); // If this throws, your RAII wrapper will unlock the mutex
// ...
}
Кроме того, во многих ситуациях это улучшит читаемость кода, поскольку вам не нужно добавлять вызов unlock()
перед каждым оператором return
.