D.5.6. Шаблон класса std::unique_lock
Шаблон класса std::unique_lock предоставляет более общую обертку владения блокировкой, чем std::lock_guard. Тип блокируемого мьютекса задается параметром шаблона Mutex и должен удовлетворять требованиям концепции BasicLockable. Вообще говоря, заданный мьютекс захватывается в конструкторе и освобождается в деструкторе, хотя имеются также дополнительные конструкторы и функции-члены, предлагающие другие возможности. Тем самым мы получаем средство захвата мьютекса в некотором блоке кода, которое гарантирует освобождение мьютекса при выходе из блока вне зависимости от того, как этот выход произведен: по достижении закрывающей скобки, в результате предложения, меняющего поток управления, например break или return, или вследствие исключения.
Функции ожидания в классе std::condition_variable требуют объекта std::unique_lock<std::mutex>, и любая конкретизация шаблона std::unique_lock может быть использована в качестве параметра типа Lockable в любом варианте функции wait из класса std::condition_variable_any.
Если тип Mutex удовлетворяет требованиям концепции Lockable, то им удовлетворяет и тип std::unique_lock<Mutex>. Если, кроме того, тип Mutex удовлетворяет требованиям концепции TimedLockable, то им удовлетворяет и тип std::unique_lock<Mutex>.
Экземпляры std::unique_lock удовлетворяют требованиям концепций MoveConstructible и MoveAssignable, но не CopyConstructible и CopyAssignable.
Определение класса
template <class Mutex>
class unique_lock {
public:
typedef Mutex mutex_type;
unique_lock() noexcept;
explicit unique_lock(mutex_type& m);
unique_lock(mutex_type& m, adopt_lock_t);
unique_lock(mutex_type& m, defer_lock_t) noexcept;
unique_lock(mutex_type& m, try_to_lock_t);
template<typename Clock, typename Duration>
unique_lock(
mutex_type& m,
std::chrono::time_point<Clock, Duration> const& absolute_time);
template<typename Rep, typename Period>
unique_lock(
mutex_type& m,
std::chrono::duration<Rep, Period> const& relative_time);
~unique_lock();
unique_lock(unique_lock const&) = delete;
unique_lock& operator=(unique_lock const&) = delete;
unique_lock(unique_lock&&);
unique_lock& operator=(unique_lock&&);
void swap(unique_lock& other) noexcept;
void lock();
bool try_lock();
template<typename Rep, typename Period>
bool try_lock_for(
std::chrono::duration<Rep, Period> const& relative_time);
template<typename Clock, typename Duration>
bool try_lock_until(
std::chrono::time_point<Clock, Duration> const& absolute_time);
void unlock();
explicit operator bool() const noexcept;
bool owns_lock() const noexcept;
Mutex* mutex() const noexcept;
Mutex* release() noexcept;
};
STD::UNIQUE_LOCK , КОНСТРУКТОР ПО УМОЛЧАНИЮ
Конструирует экземпляр std::unique_lock, с которым не ассоциирован мьютекс.
Объявление
unique_lock() noexcept;
Результат
Конструирует экземпляр std::unique_lock, с которым не ассоциирован мьютекс.
Постусловия
this->mutex() == NULL, this->owns_lock() == false.
STD::UNIQUE_LOCK , ЗАХВАТЫВАЮЩИЙ КОНСТРУКТОР
Конструирует экземпляр std::unique_lock, который захватывает указанный мьютекс.
Объявление
explicit unique_lock(mutex_type& m);
Результат
Конструирует экземпляр std::unique_lock, который ссылается на указанный мьютекс. Вызывает m.lock().
Исключения
Любое исключение, возбуждаемое m.lock().
Постусловия
this->owns_lock() == true, this->mutex() == &m.
STD::UNIQUE_LOCK , КОНСТРУКТОР, ПЕРЕНИМАЮЩИЙ БЛОКИРОВКУ
Конструирует экземпляр std::unique_lock, который владеет блокировкой указанного мьютекса.
Объявление
unique_lock(mutex_type& m, std::adopt_lock_t);
Предусловия
Вызывающий поток должен владеть блокировкой m.
Результат
Конструирует экземпляр std::unique_lock, который ссылается на указанный мьютекс и принимает владение блокировкой m, удерживаемой вызывающим потоком.
Исключения
Нет.
Постусловия
this->owns_lock() == true, this->mutex() == &m.
STD::UNIQUE_LOCK , КОНСТРУКТОР ОТЛОЖЕННОЙ БЛОКИРОВКИ
Конструирует экземпляр std::unique_lock, который не владеет блокировкой указанного мьютекса.
Объявление
unique_lock(mutex_type& m, std::defer_lock_t) noexcept;
Результат
Конструирует экземпляр std::unique_lock, который ссылается на указанный мьютекс.
Исключения
Нет.
Постусловия
this->owns_lock() == false, this->mutex() == &m.
STD::UNIQUE_LOCK , КОНСТРУКТОР ПРОБНОЙ БЛОКИРОВКИ
Конструирует экземпляр std::unique_lock, ассоциированный с указанным мьютексом, и пытается захватить этот мьютекс.
Объявление
unique_lock(mutex_type& m, std::try_to_lock_t);
Предусловия
Тип Mutex, которым конкретизирован шаблон std::unique_lock, должен удовлетворять требованиям концепции Lockable.
Результат
Конструирует экземпляр std::unique_lock, который ссылается на указанный мьютекс. Вызывает m.try_lock().
Исключения
Нет.
Постусловия
this->owns_lock() возвращает результат вызова m.try_lock(), this->mutex() == &m.
STD::UNIQUE_LOCK , КОНСТРУКТОР ПРОБНОЙ БЛОКИРОВКИ С ОТНОСИТЕЛЬНЫМ ТАЙМАУТОМ
Конструирует экземпляр std::unique_lock, ассоциированный с указанным мьютексом, и пытается захватить этот мьютекс.
Объявление
template<typename Rep, typename Period>
unique_lock(
mutex_type& m,
std::chrono::duration<Rep, Period> const& relative_time);
Предусловия
Тип Mutex, которым конкретизирован шаблон std::unique_lock, должен удовлетворять требованиям концепции TimedLockable.
Результат
Конструирует экземпляр std::unique_lock, который ссылается на указанный мьютекс. Вызывает m.try_lock_for(relative_time).
Исключения
Нет.
Постусловия
this->owns_lock() возвращает результат вызова m.try_lock_for(), this->mutex() == &m.
STD::UNIQUE_LOCK , КОНСТРУКТОР ПРОБНОЙ БЛОКИРОВКИ С АБСОЛЮТНЫМ ТАЙМАУТОМ
Конструирует экземпляр std::unique_lock, ассоциированный с указанным мьютексом, и пытается захватить этот мьютекс.
Объявление
template<typename Clock, typename Duration>
unique_lock(
mutex_type& m,
std::chrono::time_point<Clock, Duration> const& absolute_time);
Предусловия
Тип Mutex, которым конкретизирован шаблон std::unique_lock, должен удовлетворять требованиям концепции TimedLockable.
Результат
Конструирует экземпляр std::unique_lock, который ссылается на указанный мьютекс. Вызывает m.try_lock_until(relative_time).
Исключения
Нет.
Постусловия
this->owns_lock() возвращает результат вызова m.try_lock_until(), this->mutex() == &m.
STD::UNIQUE_LOCK , ПЕРЕМЕЩАЮЩИЙ КОНСТРУКТОР
Передает владение блокировкой от существующего объекта std::unique_lock вновь сконструированному.
Объявление
unique_lock(unique_lock&& other) noexcept;
Результат
Конструирует экземпляр std::unique_lock. Если объект other владел блокировкой мьютекса до вызова конструктора, то теперь этой блокировкой владеет вновь сконструированный объект std::unique_lock.
Постусловия
Для вновь сконструированного объекта std::unique_lock x, x.mutex() равно значению other.mutex() до вызова конструктора, а x.owns_lock() равно значению other.owns_lock() до вызова конструктора. other.mutex() == NULL, other.owns_lock() == false.
Исключения
Нет.
Примечание. Объекты std::unique_lock не удовлетворяют требованиям концепции CopyConstructible, поэтому копирующего конструктора не существует, существует только этот перемещающий конструктор.
STD::UNIQUE_LOCK , ПЕРЕМЕЩАЮЩИЙ ОПЕРАТОР ПРИСВАИВАНИЯ
Передает владение блокировкой от одного объекта std: :unique_ lock другому.
Объявление
unique_lock& operator=(unique_lock&& other) noexcept;
Результат
Если this->owns_lock() возвращала true до вызова этого оператора, то вызывает this->unlock(). Если объект other владел блокировкой мьютекса до присваивания, то теперь этой блокировкой владеет *this.
Постусловия
this.mutex() равно значению other.mutex() до присваивания, а this.owns_lock() равно значению other.owns_lock() до присваивания. other.mutex() == NULL, other.owns_lock() == false.
Исключения
Нет.
Примечание. Объекты std::unique_lock не удовлетворяют требованиям концепции CopyAssignable, поэтому копирующего оператора присваивания не существует, существует только этот перемещающий оператор присваивания.
STD::UNIQUE_LOCK , ДЕСТРУКТОР
Уничтожает экземпляр std::unique_lock и освобождает соответствующий мьютекс, если им владел уничтоженный экземпляр.
Объявление
~unique_lock();
Результат
Если this->owns_lock() возвращает true, то вызывает this->mutex()->unlock().
Исключения
Нет.
STD::UNIQUE_LOCK::SWAP , ФУНКЦИЯ-ЧЛЕН
Обменивает владение ассоциированными блокировками мьютекса между двумя объектами std::unique_lock.
Объявление
void swap(unique_lock& other) noexcept;
Результат
Если other владел блокировкой мьютекса до вызова, то теперь этой блокировкой владеет *this. Если *this владел блокировкой мьютекса до вызова, то теперь этой блокировкой владеет other.
Постусловия
this.mutex() равно значению other.mutex() до вызова, other.mutex() равно значению this.mutex() до вызова, this.owns_lock() равно значению other.owns_lock() до вызова, other.owns_lock() равно значению this.owns_lock() до вызова.
Исключения
Нет.
STD::SWAP , ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА
Обменивает владение ассоциированными блокировками мьютекса между двумя объектами std::unique_lock.
Объявление
void swap(unique_lock& lhs, unique_lock& rhs) noexcept;
Результат
lhs.swap(rhs)
Исключения
Нет.
STD::UNIQUE_LOCK::LOCK , ФУНКЦИЯ-ЧЛЕН
Захватывает мьютекс, ассоциированный с *this.
Объявление
void lock();
Предусловия
this->mutex() != NULL, this->owns_lock() == false.
Результат
Вызывает this->mutex()->lock().
Исключения
Любое исключение, возбужденное this->mutex()->lock(). Исключение типа std::system_error с кодом ошибки std::errc::operation_not_permitted, если this->mutex() == NULL. Исключение типа std::system_error с кодом ошибки std::errc::resource_deadlock_would_occur, если this->owns_lock() == true в момент вызова.
Постусловия
this->owns_lock() == true.
STD::UNIQUE_LOCK::TRY_LOCK , ФУНКЦИЯ-ЧЛЕН
Пытается захватить мьютекс, ассоциированный с *this.
Объявление
bool try_lock();
Предусловия
Тип Mutex, которым конкретизируется шаблон std::unique_lock, должен удовлетворять требованиям концепции Lockable. this->mutex() != NULL, this->owns_lock() == false.
Результат
Вызывает this->mutex ()->try_lock().
Возвращаемое значение
true, если вызов this->mutex()->try_lock() вернул true, иначе false.
Исключения
Любое исключение, возбужденное this->mutex()->try_lock(). Исключение типа std::system_error с кодом ошибки std::errc::operation_not_permitted, если this->mutex() == NULL. Исключение типа std::system_error с кодом ошибки std::errc::resource_deadlock_would_occur, если this->owns_lock() == true в момент вызова.
Постусловия
Если функция возвращает true, то this->owns_lock() == true, иначе this->owns_lock() == false.
STD::UNIQUE_LOCK::UNLOCK , ФУНКЦИЯ-ЧЛЕН
Освобождает мьютекс, ассоциированный с *this.
Объявление
void unlock();
Предусловия
this->mutex() != NULL, this->owns_lock() == true.
Результат
Вызывает this->mutex()->unlock().
Исключения
Любое исключение, возбужденное this->mutex()->unlock(). Исключение типа std::system_error с кодом ошибки std::errc::operation_not_permitted, если this->owns_lock() == false в момент вызова.
Постусловия
this->owns_lock() == false.
STD::UNIQUE_LOCK::TRY_LOCK_FOR , ФУНКЦИЯ-ЧЛЕН
Пытается захватить мьютекс, ассоциированный с *this, в течение указанного времени.
Объявление
template<typename Rep, typename Period>
bool try_lock_for(
std::chrono::duration<Rep, Period> const& relative_time);
Предусловия
Тип Mutex, которым конкретизируется шаблон std::unique_lock, должен удовлетворять требованиям концепции TimedLockable. this->mutex() != NULL, this->owns_lock() == false.
Результат
Вызывает this->mutex ()->try_lock_for(relative_time).
Возвращаемое значение
true, если вызов this->mutex()->try_lock_for() вернул true, иначе false.
Исключения
Любое исключение, возбужденное this->mutex()->try_lock_for(). Исключение типа std::system_error с кодом ошибки std::errc::operation_not_permitted, если this->mutex() == NULL. Исключение типа std::system_error с кодом ошибки std::errc::resource_deadlock_would_occur, если this->owns_lock() == true в момент вызова.
Постусловия
Если функция вернула true, то this->owns_lock() == true, иначе this->owns_lock() == false.
STD::UNIQUE_LOCK::TRY_LOCK_UNTIL , ФУНКЦИЯ-ЧЛЕН
Пытается захватить мьютекс, ассоциированный с *this, в течение указанного времени.
Объявление
template<typename Clock, typename Duration>
bool try_lock_until(
std::chrono::time_point<Clock, Duration> const& absolute_time);
Предусловия
Тип Mutex, которым конкретизируется шаблон std::unique_lock, должен удовлетворять требованиям концепции TimedLockable. this->mutex() != NULL, this->owns_lock() == false.
Результат
Вызывает this->mutex()->try_lock_until(absolute_time).
Возвращаемое значение
true, если вызов this->mutex()->try_lock_until() вернул true, иначе false.
Исключения
Любое исключение, возбужденное this->mutex()->try_lock_until(). Исключение типа std::system_error с кодом ошибки std::errc::operation_not_permitted, если this->mutex() == NULL. Исключение типа std::system_error с кодом ошибки std::errc::resource_deadlock_would_occur, если this->owns_lock() == true в момент вызова.
Постусловия
Если функция вернула true, то this->owns_lock() == true, иначе this->owns_lock() == false.
STD::UNIQUE_LOCK::OPERATOR BOOL , ФУНКЦИЯ-ЧЛЕН
Проверяет, владеет ли *this блокировкой мьютекса.
Объявление
explicit operator bool() const noexcept;
Возвращаемое значение this->owns_lock(). Исключения
Нет.
Примечание. Это оператор явного преобразования, поэтому он вызывается неявно только в контекстах, где результат используется как булевское значение, а не тогда, когда результат трактуется как целое, равное 0 или 1.
STD::UNIQUE_LOCK::OWNS_LOCK , ФУНКЦИЯ-ЧЛЕН
Проверяет, владеет ли *this блокировкой мьютекса.
Объявление
bool owns_lock() const noexcept;
Возвращаемое значение
true, если *this владеет блокировкой мьютекса, иначе false.
Исключения
Нет.
STD::UNIQUE_LOCK::MUTEX , ФУНКЦИЯ-ЧЛЕН
Возвращает мьютекс, ассоциированный с *this, если таковой имеется.
Объявление
mutex_type* mutex() const noexcept;
Возвращаемое значение
Указатель на мьютекс, ассоциированный с *this, если таковой имеется, иначе NULL.
Исключения
Нет.
STD::UNIQUE_LOCK::RELEASE , ФУНКЦИЯ-ЧЛЕН
Возвращает мьютекс, ассоциированный с *this, если таковой имеется, и разрывает эту ассоциацию.
Объявление
mutex_type* release() noexcept;
Результат
Разрывает ассоциацию мьютекса с *this, не освобождая блокировку.
Возвращаемое значение
Указатель на мьютекс, ассоциированный с *this, если таковой имеется, иначе NULL.
Постусловия
this->mutex() == NULL, this->owns_lock() == false.
Исключения
Нет.
Примечание. Если this->owns_lock() вернула бы до этого обращения true, то с этого момента за освобождение мьютекса отвечает вызывающая программа.