Рекомендуемый способ использования mutex
для блокировки критической области кода — через RAII, т.е.
mutex_type mutex;
{ // start of critical region
std::lock_guard<mutex_type> lock(mutex); // first statement in critical region
// ... do critical stuff, may throw an exception
} // end of critical region
так что, когда в критической области возникает исключение, мьютекс все равно будет разблокирован (деструктором std::lock_guard
). Однако таким образом члены mutex::lock()
и mutex::unlock()
никогда не вызываются явным образом кодом пользователя.
Вопрос. Что является основным идиоматическим явным использованием mutex::lock()
?
Я спрашиваю, иначе нет смысла иметь mutex::lock()
публичного члена, продвигающего плохой код (тот, который избегает std::lock_guard
).
Изменить Поскольку и std::lock_guard<>
, и std::mutex
определены в одном и том же заголовке, std::mutex
может легко подружиться с std::lock_guard<std::mutex
и защитить свои методы lock()
и unlock()
:
class mutex // use only with lock_guard<mutex>
{
friend class lock_guard<mutex>; // support acquire-release semantic via RAII
friend class scoped_lock_guard<mutex>; // for supporting more complicated semantic,
// possibly remembering the mutex state.
// ...
protected:
void lock();
bool try_lock();
void unlock();
};
class raw_mutex // use if you absolutely must explicitly lock, try_lock, or unlock
: public mutex
{
public:
using mutex::lock;
using mutex::try_lock;
using mutex::unlock;
};
Аргумент в отношении ответа на мой вопрос заключается в том, что единственный безопасный способ использования mutex::lock()
— это использование RAII. Таким образом, единственно разумное явное использование должно включать только noexcept
методов между вызовами lock
(или try_lock
) и unlock
. Однако, поскольку noexcept
является только наводящим на размышления и ничего не обещает, такое использование было бы небезопасным. Вопрос правильно?
thread_start_lock
- person Lightness Races in Orbit   schedule 06.04.2014thread_start_lock.unlock()
всегда вызывается тем же потоком, что иthread_start_lock.lock()
, на самом деле все выглядит наоборот. - person Walter   schedule 08.04.2014unlock()
в разблокированном мьютексе или в другом потоке, чем тот, который вызвалlock()
. Неясно, избегает ли ваш код их. - person Walter   schedule 10.04.2014unlock()
при построении иlock()
при разрушении. Странный случай, но все же. Делать это очень сложным кажется плохой идеей. - person Dave S   schedule 09.01.2016unlock()
s. Однако такую двойную защиту можно было бы более четко реализовать в одном объекте, таком какscoped_lock_guard
. - person Walter   schedule 10.01.2016