why std::lock() supports deallock avoidence but std::try_lock() does not?

  • A+
Category:Languages

I thought the difference between std::lock() and std::try_lock() is only in try_lock() , if locks are not available , immediately it will return false while in the case of std::lock(), it will go in blocked state.

Cpp reference for std::lock

void lock( Lockable1& lock1, Lockable2& lock2, LockableN&... lockn ); 

Locks the given Lockable objects lock1, lock2, ..., lockn using a deadlock avoidance algorithm to avoid deadlock.

Cpp reference by try_lock

int try_lock( Lockable1& lock1, Lockable2& lock2, LockableN&... lockn); 

Tries to lock each of the given Lockable objects lock1, lock2, ..., lockn by calling try_lock in order beginning with the first.

I have following two questions:

  1. Why std::lock() provides deadlock avoidence but std::try_lock doesn't?
  2. why in std::lock , order of lock doesn't matter( it could be lock2 , lock 3, lock1, ...) while in std::try_lock() order of locks are maintained (lock1, lock2, lock3....)

  1. Why std::lock() provides deadlock avoidence but std::try_lock doesn't?

It doesn't need to. If the try_lock fails to lock all members then it releases all members. You can't get a deadlock from try_lock if another thread owns some or all of these resources since you will return immediately.

From try_lock:

If a call to try_lock fails, no further call to try_lock is performed, unlock is called for any locked objects and a 0-based index of the object that failed to lock is returned.


  1. why in std::lock , order of lock doesn't matter( it could be lock2 , lock 3, lock1, ...) while in std::try_lock() order of locks are maintained (lock1, lock2, lock3....)

I suspect because of ease. There is no dead-lock avoidance algorithm required because you either lock all of them, or you can't lock one in which case you release all of them. For this reason the easiest locking approach is to try_lock beginning with the first and moving through the variadic template list. Furthermore the return value indicates that it will return the index of the first failed lock. In order to achieve this you must iterate from left to right.

Comment

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