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:
std::lock()
provides deadlock avoidence but std::try_lock
doesn't?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....)This compliant solution uses Standard Template Library facilities to ensure that deadlock does not occur due to circular wait conditions. The std::lock() function takes a variable number of lockable objects and attempts to lock them such that deadlock does not occur [ISO/IEC 14882-2014].
std::lock. Locks the given Lockable objects lock1 , lock2 , ... , lockn using a deadlock avoidance algorithm to avoid deadlock. The objects are locked by an unspecified series of calls to lock , try_lock , and unlock .
One of the most common ways of avoiding a deadlock is to always lock the two mutexes in the same order. If we always lock mutex A before mutex B, then we'll never have a deadlock.
mutex::try_lockTries to lock the mutex. Returns immediately. On successful lock acquisition returns true, otherwise returns false. This function is allowed to fail spuriously and return false even if the mutex is not currently locked by any other thread.
- 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.
- 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With