No, Rust does not have a function equivalent to C++'s std::lock
.
Based on the fact that it doesn't seem to be in the std::sync
documentation and Googling brings up nothing useful, I'm pretty confident in this assertion.
Why not? Well, if I may editorialize a bit, std::lock
isn't as broadly useful as you might hope. Deadlock avoidance is nontrivial and every algorithm will have plausible corner cases that result in poor performance or even livelock. There is no one-size-fits-all deadlock avoidance algorithm.¹ (See Is std::lock() ill-defined, unimplementable, or useless?) Putting a deadlock-avoiding lock
function in the standard library suggests that it's a good default choice, and perhaps encourages its use without regard for its implementation. Most real-life applications probably would do as well with a simpler (and less general-purpose) algorithm.
There are crates that provide deadlock avoidance by other means. For instance, tracing-mutex provides locking types that create a dependency graph at runtime and will panic instead of deadlocking if the dependency graph contains a cycle. parking_lot has an experimental deadlock_detection
feature (but I'm not sure how it works). Curiously, I didn't find any crates that provide a C++ std::sort
equivalent with backing off.
Anyway, nothing stops you writing your own "backing off" algorithm to solve this problem; it's just not part of the standard library.
¹ In fairness, you could make the same argument for other functions Rust does have, like [T]::sort
. But there are many applications where sorting is not a bottleneck and any reasonably fast algorithm is good enough. Deadlock avoidance is both less likely to be necessary in general, and more likely to be performance-sensitive when it does appear.
std::lock
works, but (unless you follow mmstick's answer in lumping the data together and locking/unlocking it at once) I don't see how you could ever guarantee no deadlocks. Sure, you could write a macro to do them in the right order -- but then you've just mutated the problem of checking that you always lock them in the right order into the barely-easier problem of checking that you always use the macro and never call .lock() directly. Right? – Optional