folly::lock

Acquire locks on many lockables or synchronized instances in such a way that the sequence of calls within the function does not cause deadlocks.

Synopsis

Declared in <folly/Synchronized.h>

template<
    typename LockableOne,
    typename LockableTwo,
    typename... Lockables>
void
lock(
    LockableOne& one,
    LockableTwo& two,
    Lockables&... lockables);

Description

This can often result in a performance boost as compared to simply acquiring your locks in an ordered manner. Even for very simple cases. The algorithm tried to adjust to contention by blocking on the mutex it thinks is the best fit, leaving all other mutexes open to be locked by other threads. See the benchmarks in folly/test/SynchronizedBenchmark.cpp for more

This works differently as compared to the locking algorithm in libstdc++ and is the recommended way to acquire mutexes in a generic order safe manner. Performance benchmarks show that this does better than the one in libstdc++ even for the simple cases

Usage is the same as std::lock() for arbitrary lockables

folly::lock(one, two, three);

To make it work with folly::Synchronized you have to specify how you want the locks to be acquired, use the folly::wlock(), folly::rlock(), folly::ulock() and folly::lock() helpers defined below

auto [one, two]= lock(folly::wlock(a), folly::rlock(b));

Note that you can/must avoid the folly:: namespace prefix on the lock() function if you use the helpers, ADL lookup is done to find the lock function

This will execute the deadlock avoidance algorithm and acquire a write lock for a and a read lock for b

Parameters

NameDescription
oneThe first lockable to acquire.
twoThe second lockable to acquire.
lockablesAny additional lockables to acquire.