Why put std::lock before std::lock_guard

  • A+
Category:Languages

Moving forward with Concurrency In Action I have reached the following example.
Tha author states that if we everytime lock 2 mutexes in the same order, then we are guaranteed to avoid deadlocks.
Consider this example from the book:

class X {     private:     some_big_object some_detail;     std::mutex m; public:     X(some_big_object const& sd):some_detail(sd){}     friend void swap(X& lhs, X& rhs)     {        if(&lhs==&rhs){return;}        std::lock(lhs.m,rhs.m);        std::lock_guard<std::mutex> lock_a(lhs.m,std::adopt_lock);        std::lock_guard<std::mutex> lock_b(rhs.m,std::adopt_lock);        swap(lhs.some_detail,rhs.some_detail);     } }; 
  1. Why do we apply the std::lock and then apply 2 std::lock_guards with std::adopt_lock instead of just applying 2 std::lock_guards one after another??
  2. Why cant we just put this 2 std::mutexes in the std::scoped_lock??

Why do we apply the std::lock and then apply 2 std::lock_guards with std::adopt_lock instead of just applying 2 std::lock_guards one after another??

If you used two std::lock_guard without std::lock the order of locking for a = b; would be the opposite of b = a;, where a and b are Xs. If one thread tried a = b; while another tried b = a; they could deadlock. The first thread would own the lock on a's mutex and wait for b's while the second thread would own the lock on b's mutex and wait for a's. Using std::lock ensures that the locking order is always consistent.

Why cant we just put this 2 std::mutexes in the std::scoped_lock??

If you look at the date of publication for the article you linked, c++17 did not exist yet. Since std::scoped_lock was introduced by c++17, it could not have been used in the article. This kind of locking problem is what std::scoped_lock is design to solve and should be used in modern code.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: