I'm trying to determine if std::scoped_lock tries to establish an ordering or mutex id to acquire locks in a prescribed order. Is not clear to me that it does it from a somewhat brief looking at a browsable implementation I found googling around.
In case it is not doing that, What would be the closest to standard implementation of acquiring an ordered set of locks?
Typically the cleanest way to avoid deadlocks is to always acquire a group of locks in the same order (and yes, sure, always release them all before trying to acquire new locks again, but perhaps 2PL is a little beyond the scope of what std::scoped_lock
should aim to do)
CodePudding user response:
The order for std::lock
isn't defined until run-time, and it is not fixed. It is discovered experimentally by the algorithm for each individual call to std::lock
. The second call to std::lock
could lock the mutexes in a different order than the first, even though both calls might use the same list of mutexes in the same order at the call site.
Here is a detailed performance analysis of several possible implementations of std::lock
: http://howardhinnant.github.io/dining_philosophers.html
Using a fixed ordering of the mutexes is one of the algorithms that is performance-compared in the above link. It is not the best performing algorithm for the experiments conducted.
The libstdc implementation the OP points to is a high quality implementation of what the analysis labels "Smart & Polite"
CodePudding user response:
scoped_lock
's constructor is stated to call std::lock
on its mutexes, so its behavior is governed by this function. And std::lock
is specifically defined to avoid deadlocks on what it locks. The order it locks the mutexes in is undefined, but it won't result in a deadlock.