Why acquiring multiple mutexes manually (m1.lock(); m2.lock();) frequently causes circular deadlocks:
If Thread A locks m1 then waits for m2, while Thread B locks m2 then waits for m1, both threads halt forever.
The Fix in C++17:
void TransferFunds(Account& from, Account& to, double amount) {
// std::scoped_lock acquires any number of mutexes deadlock-free using RAII
std::scoped_lock lock(from.m_mutex, to.m_mutex);
from.m_balance -= amount;
to.m_balance += amount;
}std::scoped_lock uses a deadlock avoidance algorithm (like std::lock) and unlocks automatically upon scope exit!