Namespaces
Variants

std:: unique_lock

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
(C++11)
(C++11)
unique_lock
(C++11)
(C++11)
(C++11)
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
Определено в заголовочном файле <mutex>
template < class Mutex >
class unique_lock ;
(начиная с C++11)

Класс unique_lock является универсальной обёрткой владения мьютексом, позволяющей отложенную блокировку, попытки блокировки с ограничением по времени, рекурсивную блокировку, передачу владения блокировкой и использование с переменными условия.

Класс unique_lock является перемещаемым, но не копируемым — он удовлетворяет требованиям MoveConstructible и MoveAssignable , но не требованиям CopyConstructible или CopyAssignable .

Класс unique_lock удовлетворяет требованиям BasicLockable . Если Mutex удовлетворяет требованиям Lockable , unique_lock также удовлетворяет требованиям Lockable (например, может использоваться в std::lock ); если Mutex удовлетворяет требованиям TimedLockable , unique_lock также удовлетворяет требованиям TimedLockable .

Содержание

Параметры шаблона

Mutex - тип мьютекса для блокировки. Тип должен удовлетворять BasicLockable требованиям

Вложенные типы

Тип Определение
mutex_type Mutex

Функции-члены

создает объект unique_lock , опционально блокируя (т.е. получая владение) предоставленный мьютекс
(public member function)
разблокирует (т.е. освобождает владение) связанный мьютекс, если владеет им
(public member function)
разблокирует (т.е. освобождает владение) мьютекс, если владеет им, и получает владение другим
(public member function)
Блокировка
блокирует (т.е. получает владение) связанный мьютекс
(public member function)
пытается заблокировать (т.е. получить владение) связанный мьютекс без блокировки
(public member function)
пытается заблокировать (т.е. получить владение) связанный TimedLockable мьютекс, возвращает управление если мьютекс был недоступен в течение указанного времени
(public member function)
пытается заблокировать (т.е. получить владение) связанный TimedLockable мьютекс, возвращает управление если мьютекс был недоступен до достижения указанной точки времени
(public member function)
разблокирует (т.е. освобождает владение) связанный мьютекс
(public member function)
Модификаторы
обменивает состояние с другим std::unique_lock
(public member function)
отсоединяет связанный мьютекс без разблокировки (т.е. освобождения владения) его
(public member function)
Наблюдатели
возвращает указатель на связанный мьютекс
(public member function)
проверяет, владеет ли блокировка (т.е. заблокировала ли) своим связанным мьютексом
(public member function)
проверяет, владеет ли блокировка (т.е. заблокировала ли) своим связанным мьютексом
(public member function)

Функции, не являющиеся членами класса

специализирует алгоритм std::swap
(шаблон функции)

Примечания

Распространённая ошибка новичков — «забыть» дать переменной unique_lock имя, например: std :: unique_lock ( mtx ) ; (что создаёт переменную unique_lock с именем mtx по умолчанию) или std :: unique_lock { mtx } ; (что создаёт prvalue-объект, который немедленно уничтожается), тем самым фактически не создавая блокировку, удерживающую мьютекс до конца области видимости.

Пример

#include <iostream>
#include <mutex>
#include <thread>
struct Box
{
    explicit Box(int num) : num_things{num} {}
    int num_things;
    std::mutex m;
};
void transfer(Box& from, Box& to, int num)
{
    // пока не захватываем блокировки
    std::unique_lock lock1{from.m, std::defer_lock};
    std::unique_lock lock2{to.m, std::defer_lock};
    // захватываем обе блокировки без взаимной блокировки
    std::lock(lock1, lock2);
    from.num_things -= num;
    to.num_things += num;
    // мьютексы "from.m" и "to.m" разблокируются в деструкторах unique_lock
}
int main()
{
    Box acc1{100};
    Box acc2{50};
    std::thread t1{transfer, std::ref(acc1), std::ref(acc2), 10};
    std::thread t2{transfer, std::ref(acc2), std::ref(acc1), 5};
    t1.join();
    t2.join();
    std::cout << "acc1: " << acc1.num_things << "\n"
                 "acc2: " << acc2.num_things << '\n';
}

Вывод:

acc1: 95
acc2: 55

Отчеты о дефектах

Следующие отчеты об изменениях в поведении, содержащие описания дефектов, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Applied to Behavior as published Correct behavior
LWG 2981 C++17 redundant deduction guide from unique_lock<Mutex> was provided removed

Смотрите также

(C++11)
блокирует указанные мьютексы, блокируется если любой из них недоступен
(function template)
(C++11)
реализует строго ограниченный областью видимости обёрточный класс владения мьютексом
(class template)
RAII-обёртка для нескольких мьютексов, избегающая взаимных блокировок
(class template)
(C++11)
предоставляет базовые средства взаимного исключения
(class)