Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

c++11

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....)
like image 867
Alok Avatar asked May 11 '18 06:05

Alok


People also ask

How does std :: lock avoid deadlock?

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].

What does std :: lock do?

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 .

How can we avoid deadlock in C++?

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.

What is a Try_lock?

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.


1 Answers

  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.

like image 200
Fantastic Mr Fox Avatar answered Oct 09 '22 10:10

Fantastic Mr Fox