GSP
Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Support
Contact Us
Online Help
Handbooks
Domain Status
Man Pages

FAQ
Virtual Servers
Pricing
Billing
Technical

Network
Facilities
Connectivity
Topology Map

Miscellaneous
Server Agreement
Year 2038
Credits
 

USA Flag

 

 

Man Pages
std::lock(3) C++ Standard Libary std::lock(3)

std::lock - std::lock


Defined in header <mutex>
template< class Lockable1, class Lockable2, class... LockableN > (since C++11)
void lock( Lockable1& lock1, Lockable2& lock2, LockableN&... lockn );


Locks the given Lockable objects lock1, lock2, ..., lockn using a deadlock avoidance
algorithm to avoid deadlock.


The objects are locked by an unspecified series of calls to lock, try_lock, and
unlock. If a call to lock or unlock results in an exception, unlock is called for
any locked objects before rethrowing.


lock1, lock2, ... , lockn - the Lockable objects to lock


(none)


Boost provides a version of this function that takes a sequence of Lockable objects
defined by a pair of iterators.


std::scoped_lock offers a RAII wrapper for this function, and is generally preferred
to a naked call to std::lock.


The following example uses std::lock to lock pairs of mutexes without deadlock.

// Run this code


#include <mutex>
#include <thread>
#include <iostream>
#include <vector>
#include <functional>
#include <chrono>
#include <string>


struct Employee {
Employee(std::string id) : id(id) {}
std::string id;
std::vector<std::string> lunch_partners;
std::mutex m;
std::string output() const
{
std::string ret = "Employee " + id + " has lunch partners: ";
for( const auto& partner : lunch_partners )
ret += partner + " ";
return ret;
}
};


void send_mail(Employee &, Employee &)
{
// simulate a time-consuming messaging operation
std::this_thread::sleep_for(std::chrono::seconds(1));
}


void assign_lunch_partner(Employee &e1, Employee &e2)
{
static std::mutex io_mutex;
{
std::lock_guard<std::mutex> lk(io_mutex);
std::cout << e1.id << " and " << e2.id << " are waiting for locks" << std::endl;
}


// use std::lock to acquire two locks without worrying about
// other calls to assign_lunch_partner deadlocking us
{
std::lock(e1.m, e2.m);
std::lock_guard<std::mutex> lk1(e1.m, std::adopt_lock);
std::lock_guard<std::mutex> lk2(e2.m, std::adopt_lock);
// Equivalent code (if unique_locks are needed, e.g. for condition variables)
// std::unique_lock<std::mutex> lk1(e1.m, std::defer_lock);
// std::unique_lock<std::mutex> lk2(e2.m, std::defer_lock);
// std::lock(lk1, lk2);
// Superior solution available in C++17
// std::scoped_lock lk(e1.m, e2.m);
{
std::lock_guard<std::mutex> lk(io_mutex);
std::cout << e1.id << " and " << e2.id << " got locks" << std::endl;
}
e1.lunch_partners.push_back(e2.id);
e2.lunch_partners.push_back(e1.id);
}
send_mail(e1, e2);
send_mail(e2, e1);
}


int main()
{
Employee alice("alice"), bob("bob"), christina("christina"), dave("dave");


// assign in parallel threads because mailing users about lunch assignments
// takes a long time
std::vector<std::thread> threads;
threads.emplace_back(assign_lunch_partner, std::ref(alice), std::ref(bob));
threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(bob));
threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(alice));
threads.emplace_back(assign_lunch_partner, std::ref(dave), std::ref(bob));


for (auto &thread : threads) thread.join();
std::cout << alice.output() << '\n' << bob.output() << '\n'
<< christina.output() << '\n' << dave.output() << '\n';
}


alice and bob are waiting for locks
alice and bob got locks
christina and bob are waiting for locks
christina and bob got locks
christina and alice are waiting for locks
christina and alice got locks
dave and bob are waiting for locks
dave and bob got locks
Employee alice has lunch partners: bob christina
Employee bob has lunch partners: alice christina dave
Employee christina has lunch partners: bob alice
Employee dave has lunch partners: bob


unique_lock implements movable mutex ownership wrapper
(C++11) (class template)
try_lock attempts to obtain ownership of mutexes via repeated calls to try_lock
(C++11) (function template)
scoped_lock deadlock-avoiding RAII wrapper for multiple mutexes
(C++17) (class template)

2022.07.31 http://cppreference.com

Search for    or go to Top of page |  Section 3 |  Main Index

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with ManDoc.