Namespaces
Variants

std:: lock_guard

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)
lock_guard
(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 lock_guard ;
(depuis C++11)

La classe lock_guard est un wrapper de mutex qui fournit un mécanisme pratique de style RAII pour posséder un mutex pendant la durée d'un bloc de portée.

Lorsqu'un objet lock_guard est créé, il tente de prendre la possession du mutex qui lui est donné. Lorsque le contrôle quitte la portée dans laquelle l'objet lock_guard a été créé, le lock_guard est détruit et le mutex est libéré.

La classe lock_guard n'est pas copiable.

Table des matières

Paramètres du modèle

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

Types membres

Type de membre Définition
mutex_type Mutex

Fonctions membres

construit un lock_guard , verrouillant optionnellement le mutex donné
(fonction membre publique)
détruit l'objet lock_guard , déverrouille le mutex sous-jacent
(fonction membre publique)
operator=
[deleted]
non assignable par copie
(fonction membre publique)

Notes

Une erreur courante chez les débutants est d'oublier de donner un nom à une variable lock_guard , par exemple en écrivant std :: lock_guard { mtx } . Cela construit un objet prvalue qui est immédiatement détruit, ne créant donc pas réellement un verrou qui maintient un mutex pour le reste de la portée.

std::scoped_lock offre une alternative à lock_guard qui permet de verrouiller plusieurs mutex en utilisant un algorithme d'évitement d'interblocage.

(depuis C++17)

Exemple

Illustre les incréments sécurisés et non sécurisés d'une variable volatile par deux threads.

#include <iostream>
#include <mutex>
#include <string_view>
#include <syncstream>
#include <thread>
volatile int g_i = 0;
std::mutex g_i_mutex;  // protects g_i
void safe_increment(int iterations)
{
    const std::lock_guard<std::mutex> lock(g_i_mutex);
    while (iterations-- > 0)
        g_i = g_i + 1;
    std::cout << "thread #" << std::this_thread::get_id() << ", g_i: " << g_i << '\n';
    // g_i_mutex is automatically released when lock goes out of scope
}
void unsafe_increment(int iterations)
{
    while (iterations-- > 0)
        g_i = g_i + 1;
    std::osyncstream(std::cout) << "thread #" << std::this_thread::get_id()
                                << ", g_i: " << g_i << '\n';
}
int main()
{
    auto test = [](std::string_view fun_name, auto fun)
    {
        g_i = 0;
        std::cout << fun_name << ":\nbefore, g_i: " << g_i << '\n';
        {
            std::jthread t1(fun, 1'000'000);
            std::jthread t2(fun, 1'000'000);
        }
        std::cout << "after, g_i: " << g_i << "\n\n";
    };
    test("safe_increment", safe_increment);
    test("unsafe_increment", unsafe_increment);
}

Sortie possible :

safe_increment:
before, g_i: 0
thread #140121493231360, g_i: 1000000
thread #140121484838656, g_i: 2000000
after, g_i: 2000000
unsafe_increment:
before, g_i: 0
thread #140121484838656, g_i: 1028945
thread #140121493231360, g_i: 1034337
after, g_i: 1034337

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 S'applique à Comportement publié Comportement corrigé
LWG 2981 C++17 un guide de déduction redondant de lock_guard<Mutex> était fourni supprimé

Voir aussi

implémente un wrapper de propriété de mutex déplaçable
(modèle de classe)
wrapper RAII évitant les interblocages pour plusieurs mutex
(modèle de classe)