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
Défini dans l'en-tête <mutex>
template < class Mutex >
class unique_lock ;
(depuis C++11)

La classe unique_lock est un wrapper de propriété de mutex à usage général permettant le verrouillage différé, les tentatives de verrouillage avec contraintes temporelles, le verrouillage récursif, le transfert de propriété du verrou et l'utilisation avec des variables de condition.

La classe unique_lock est déplaçable, mais non copiable -- elle satisfait aux exigences de MoveConstructible et MoveAssignable mais pas celles de CopyConstructible ou CopyAssignable .

La classe unique_lock satisfait aux exigences BasicLockable . Si Mutex satisfait aux exigences Lockable , unique_lock satisfait également aux exigences Lockable (par exemple : peut être utilisé dans std::lock ) ; si Mutex satisfait aux exigences TimedLockable , unique_lock satisfait également aux exigences TimedLockable .

Table des matières

Paramètres du modèle

Mutex - le type du mutex à verrouiller. Le type doit satisfaire aux BasicLockable exigences

Types imbriqués

Type Définition
mutex_type Mutex

Fonctions membres

construit un unique_lock , verrouillant optionnellement (c'est-à-dire prenant la possession de) le mutex fourni
(fonction membre publique)
déverrouille (c'est-à-dire libère la possession de) le mutex associé, s'il est possédé
(fonction membre publique)
déverrouille (c'est-à-dire libère la possession de) le mutex, s'il est possédé, et acquiert la possession d'un autre
(fonction membre publique)
Verrouillage
verrouille (c'est-à-dire prend la possession de) le mutex associé
(fonction membre publique)
tente de verrouiller (c'est-à-dire prend la possession de) le mutex associé sans bloquer
(fonction membre publique)
tente de verrouiller (c'est-à-dire prend la possession de) le mutex TimedLockable associé, retourne si le mutex est resté indisponible pendant la durée spécifiée
(fonction membre publique)
tente de verrouiller (c'est-à-dire prend la possession de) le mutex TimedLockable associé, retourne si le mutex est resté indisponible jusqu'à ce que le point temporel spécifié soit atteint
(fonction membre publique)
déverrouille (c'est-à-dire libère la possession de) le mutex associé
(fonction membre publique)
Modificateurs
échange l'état avec un autre std::unique_lock
(fonction membre publique)
dissocie le mutex associé sans le déverrouiller (c'est-à-dire sans libérer sa possession)
(fonction membre publique)
Observateurs
retourne un pointeur vers le mutex associé
(fonction membre publique)
teste si le verrou possède (c'est-à-dire a verrouillé) son mutex associé
(fonction membre publique)
teste si le verrou possède (c'est-à-dire a verrouillé) son mutex associé
(fonction membre publique)

Fonctions non membres

spécialise l'algorithme std::swap
(modèle de fonction)

Notes

Une erreur courante chez les débutants est d'« oublier » de donner un nom à une variable unique_lock , par exemple std :: unique_lock ( mtx ) ; (qui construit par défaut une variable unique_lock nommée mtx ) ou std :: unique_lock { mtx } ; (qui construit un objet prvalue immédiatement détruit), ne construisant ainsi pas réellement un verrou qui maintient un mutex pour le reste de la portée.

Exemple

#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)
{
    // ne pas encore acquérir les verrous
    std::unique_lock lock1{from.m, std::defer_lock};
    std::unique_lock lock2{to.m, std::defer_lock};
    // verrouiller les deux unique_lock sans interblocage
    std::lock(lock1, lock2);
    from.num_things -= num;
    to.num_things += num;
    // les mutex “from.m” et “to.m” sont déverrouillés dans les destructeurs 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';
}

Sortie :

acc1: 95
acc2: 55

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Appliqué à Comportement tel que publié Comportement correct
LWG 2981 C++17 un guide de déduction redondant de unique_lock<Mutex> était fourni supprimé

Voir aussi

(C++11)
verrouille les mutex spécifiés, bloque si l'un d'eux n'est pas disponible
(modèle de fonction)
(C++11)
implémente un wrapper de propriété de mutex strictement basé sur la portée
(modèle de classe)
wrapper RAII évitant les interblocages pour plusieurs mutex
(modèle de classe)
(C++11)
fournit une fonction d'exclusion mutuelle de base
(classe)