Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is using unique_lock for a task that can be acomplished by lock_guard slower?

I am confused regarding the reason why lock_guard exists. Is it:

  1. A simpler interface than unique_lock?
  2. Better performance than unique_lock?
  3. Something else?
like image 877
NoSenseEtAl Avatar asked Oct 24 '13 16:10

NoSenseEtAl


People also ask

Does unique_lock automatically unlock?

look up how a unique_lock() behaves. @Prab, just to give the explanation: unique_lock() is automatically released when the destructor is called meaning it is exception safe and that it automatically unlocks when you leave scope.

What is the benefit of using std :: unique_lock?

There are two primary benefits to using std::unique_lock<> over std::lock_guard<> : you can transfer ownership of the lock between instances, and. the std::unique_lock<> object does not have to own the lock on the mutex it is associated with.

What is the difference between unique_lock and lock_guard?

A lock_guard always holds a lock from its construction to its destruction. A unique_lock can be created without immediately locking, can unlock at any point in its existence, and can transfer ownership of the lock from one instance to another.

What is a unique_lock?

The class unique_lock is a general-purpose mutex ownership wrapper allowing deferred locking, time-constrained attempts at locking, recursive locking, transfer of lock ownership, and use with condition variables.


2 Answers

lock_guard can be implemented with one unit of state: a pointer or reference to the Mutex type it has locked.

unique_lock has to both hold that state, and knowing if it is currently locked, as a unique_lock can have a Mutex that is not locked. This means it must have at least a bool of extra state.

lock_guard provides a zero overhead RAII lock/unlock wrapper around acquiring and releasing a Mutex. Basically the lock_guard means that there is zero reason to avoid using RAII to handle locks on a Mutex.

unique_lock can only reach zero overhead if the compiler can be convinced to notice you only use it in ways that lock_guard could be used (ie, construct it, then destroy it, without fiddling with it).

Beyond those efficiency arguments, a programmer who sees a lock_guard knows that it is going to last until end of scope without having to examine the code in the scope. A programmer who sees a unique_lock must examine all use of the variable to know if this is the case.

But the above is only half the reason.

The other half of the reason is because much of the threading library for C++11 was based off of boost libraries, which had already implemented a mostly platform independent threading library. Boost has both lock_guard and unique_lock, with nearly identical semantics to the C++11 versions.

So when the boost threading library was standardized, both where carried in, and nobody eliminated them.

like image 128
Yakk - Adam Nevraumont Avatar answered Sep 22 '22 21:09

Yakk - Adam Nevraumont


You almost answer your own question here - 1) and 2) are both good reasons. std::lock_guard is a simple scoped locking object. Features like a timeout on mutex acquisition add to the complexity of the mutex primitive, increasing both the time it takes to perform the operation and the probability of contention for the mutex. So why pay for what you don't need?

Whether 'try_locking' with or without timeouts is good design is another question; like thread cancellation, a broken design which C++11 does not implement.

like image 28
Brett Hale Avatar answered Sep 22 '22 21:09

Brett Hale