Acquire locks on many lockables or synchronized instances in such a way that the sequence of calls within the function does not cause deadlocks.
Declared in <folly/Synchronized.h>
template<
typename LockableOne,
typename LockableTwo,
typename... Lockables>
void
lock(
LockableOne& one,
LockableTwo& two,
Lockables&... lockables);
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
| Name | Description |
|---|---|
| one | The first lockable to acquire. |
| two | The second lockable to acquire. |
| lockables | Any additional lockables to acquire. |