# std::lock

From cppreference.com
< cpp‎ | thread

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

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`, `unlock`. If a call to `lock` or `unlock` results in an exception, `unlock` is called for any locked objects before rethrowing.

### Parameters

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

### Return value

(none)

### Notes

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

### Example

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);
            {
                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';
    }

Possible output:

    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

### See also

try_lock (C++11) | attempts to obtain ownership of mutexes via repeated calls to `try_lock` (function template)

Retrieved from "http://en.cppreference.com/mwiki/index.php?title=cpp/thread/lock&oldid=87851"