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
Definido en el encabezado <mutex>
template < class Mutex >
class unique_lock ;
(desde C++11)

La clase unique_lock es un contenedor de propiedad de mutex de propósito general que permite bloqueo diferido, intentos de bloqueo con restricciones de tiempo, bloqueo recursivo, transferencia de propiedad del bloqueo y uso con variables de condición.

La clase unique_lock es movible, pero no copiable -- cumple con los requisitos de MoveConstructible y MoveAssignable pero no de CopyConstructible o CopyAssignable .

La clase unique_lock cumple con los requisitos de BasicLockable . Si Mutex cumple con los requisitos de Lockable , unique_lock también cumple con los requisitos de Lockable (ej.: puede ser usado en std::lock ); si Mutex cumple con los requisitos de TimedLockable , unique_lock también cumple con los requisitos de TimedLockable .

Contenidos

Parámetros de plantilla

Mutex - el tipo del mutex a bloquear. El tipo debe cumplir con los BasicLockable requisitos

Tipos anidados

Tipo Definición
mutex_type Mutex

Funciones miembro

construye un unique_lock , opcionalmente bloqueando (es decir, tomando posesión de) el mutex proporcionado
(función miembro pública)
desbloquea (es decir, libera la posesión de) el mutex asociado, si está en posesión
(función miembro pública)
desbloquea (es decir, libera la posesión de) el mutex, si está en posesión, y adquiere la posesión de otro
(función miembro pública)
Bloqueo
bloquea (es decir, toma posesión de) el mutex asociado
(función miembro pública)
intenta bloquear (es decir, tomar posesión de) el mutex asociado sin bloquear
(función miembro pública)
intenta bloquear (es decir, tomar posesión de) el mutex TimedLockable asociado, retorna si el mutex ha estado no disponible durante la duración de tiempo especificada
(función miembro pública)
intenta bloquear (es decir, tomar posesión de) el mutex TimedLockable asociado, retorna si el mutex ha estado no disponible hasta que se alcanza el punto de tiempo especificado
(función miembro pública)
desbloquea (es decir, libera la posesión de) el mutex asociado
(función miembro pública)
Modificadores
intercambia el estado con otro std::unique_lock
(función miembro pública)
disocia el mutex asociado sin desbloquearlo (es decir, liberar la posesión de) él
(función miembro pública)
Observadores
retorna un puntero al mutex asociado
(función miembro pública)
prueba si el bloqueo posee (es decir, ha bloqueado) su mutex asociado
(función miembro pública)
prueba si el bloqueo posee (es decir, ha bloqueado) su mutex asociado
(función miembro pública)

Funciones no miembro

especializa el algoritmo std::swap
(plantilla de función)

Notas

Un error común de principiantes es "olvidar" darle un nombre a una variable unique_lock , por ejemplo std :: unique_lock ( mtx ) ; (que construye por defecto una variable unique_lock llamada mtx ) o std :: unique_lock { mtx } ; (que construye un objeto prvalue que se destruye inmediatamente), por lo tanto no se construye realmente un bloqueo que mantenga un mutex durante el resto del ámbito.

Ejemplo

#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)
{
    // no tomar los bloqueos aún
    std::unique_lock lock1{from.m, std::defer_lock};
    std::unique_lock lock2{to.m, std::defer_lock};
    // bloquear ambos unique_locks sin interbloqueo
    std::lock(lock1, lock2);
    from.num_things -= num;
    to.num_things += num;
    // los mutex “from.m” y “to.m” se desbloquean en los destructores de 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';
}

Salida:

acc1: 95
acc2: 55

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares publicados anteriormente de C++.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 2981 C++17 se proporcionaba una guía de deducción redundante de unique_lock<Mutex> eliminada

Véase también

(C++11)
bloquea los mutex especificados, se bloquea si alguno no está disponible
(plantilla de función)
(C++11)
implementa un contenedor de propiedad de mutex estrictamente basado en ámbito
(plantilla de clase)
contenedor RAII que evita interbloqueos para múltiples mutex
(plantilla de clase)
(C++11)
proporciona facilidad básica de exclusión mutua
(clase)