`std::lock` acquires two or more mutexes together without deadlock among those mutexes. It avoids the risk of fixed-order locking when threads access the same pair of objects in opposite orders. section 3.2.4
After locking, construct a `std::lock_guard` for each mutex with `std::adopt_lock`, so each guard takes ownership of an existing lock and releases it on function exit, including during exception unwinding. If an acquisition throws, `std::lock` releases any mutexes it has already acquired. Check that the mutexes are distinct: locking a `std::mutex` already held by the same thread is undefined behavior. section 3.2.4
Listing 3.6. Using std::lock() and std::lock_guard in a swap operation
class some_big_object;
void swap(some_big_object& lhs,some_big_object& rhs);
class X
{
private:
some_big_object some_detail;
std::mutex m;
public:
X(some_big_object const& sd):some_detail(sd){}
friend void swap(X& lhs, X& rhs)
{
if(&lhs==&rhs)
return;
std::lock(lhs.m,rhs.m); #1
std::lock_guard<std::mutex> lock_a(lhs.m,std::adopt_lock); #2
std::lock_guard<std::mutex> lock_b(rhs.m,std::adopt_lock); #3
swap(lhs.some_detail,rhs.some_detail);
}
};
!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":13,\"ch\":68},{\"line\":13,\"ch\":70}],[{\"line\":14,\"ch\":68},{\"line\":14,\"ch\":70}],[{\"line\":15,\"ch\":68},{\"line\":15,\"ch\":70}]]"}
!@%STYLE%@!
See the two-object swap example, which locks both objects’ mutexes before exchanging their protected data. section 3.2.4
