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, то с этого момента за освобождение мьютекса отвечает вызывающая программа.