I'm not quite sure why std::unique_lock<std::mutex>
is useful over just using a normal lock. An example in the code I'm looking at is:
{//aquire lock
std::unique_lock<std::mutex> lock(queue_mutex);
//add task
tasks.push_back(std::function<void()>(f));
}//release lock
why would this preferred over
queue_mutex.lock();
//add task
//...
queue_mutex.unlock();
do these snippets of code accomplish the same thing?
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.
(since C++11) 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.
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.
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.
[Do] these snippets of code accomplish the same thing?
No.
The first one will release the lock at the end of the block, no matter what the block is. The second will not release the lock at the end if the critical section is exited with a break
, continue
, return
, goto
, exception, or any other kind of non-local jump that I'm forgetting about.
The use of unique_lock
offers resiliency in the face of changes and errors.
return
for example)in any case, the lock is automatically released.
On the other hand, if you attempt to do it manually, you may miss a case. And even if you don't right now, a later edit might.
Note: this is a usual idiom in C++, referred to as SBRM (Scoped Bound Resources Management) where you tie down a clean-up action to stack unwinding so you are assured that, unless crash/ungraceful exit, it is executed.
It also shows off RAII (Resources Acquisition is Initialization) since the very construction of unique_lock
acquires the resource (here the mutex). Despite its name, this acronym is also colloquially used to refer to deterministic release at destruction time, which covers a broader scope than SBRM since it refers to all kind of deterministic releases, not only those based on stack unwinding.
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