Namespaces
Variants
Actions

std::lock_guard

From cppreference.com
< cpp‎ | thread
 
 
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(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
 
 
Defined in header <mutex>
template<class Mutex >
class lock_guard;
(since C++11)

The class lock_guard is a mutex wrapper that provides a convenient RAII-style mechanism for owning a mutex for the duration of a scoped block.

When a lock_guard object is created, it attempts to take ownership of the mutex it is given. When control leaves the scope in which the lock_guard object was created, the lock_guard is destructed and the mutex is released.

The lock_guard class is non-copyable.

Contents

[edit]Template parameters

Mutex - the type of the mutex to lock. The type must meet the BasicLockable requirements

[edit]Member types

Member type Definition
mutex_type Mutex

[edit]Member functions

constructs a lock_guard, optionally locking the given mutex
(public member function)[edit]
destructs the lock_guard object, unlocks the underlying mutex
(public member function)[edit]
operator=
[deleted]
not copy-assignable
(public member function)[edit]

[edit]Notes

A common beginner error is to forget to give a lock_guard variable a name, such as by std::lock_guard{mtx}. This constructs a prvalue object that is immediately destroyed, thereby not actually constructing a lock that holds a mutex for the rest of the scope.

std::scoped_lock offers an alternative for lock_guard that provides the ability to lock multiple mutexes using a deadlock avoidance algorithm.

(since C++17)

[edit]Example

Demonstrates safe and unsafe increments of a volatile variable by two threads.

#include <iostream>#include <mutex>#include <string_view>#include <syncstream>#include <thread>   volatileint 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);}

Possible output:

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

[edit]Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

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

[edit]See also

implements movable mutex ownership wrapper
(class template)[edit]
deadlock-avoiding RAII wrapper for multiple mutexes
(class template)[edit]
close