49

When should I prefer the first piece of code to the second, and do they have fundamental differences

std::mutex mtx;
mtx.lock();
... //protected stuff
mtx.unlock();
... //non-protected stuff
mtx.lock();
... //etc

and

std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);
... //protected stuff
lck.unlock();
... //non-protected stuff
lck.lock();
... //etc

I do understand that lock_guard is basically a unique_lock without the lock and unlock functions, but I'm having hard time differentiating a mutex and a lock using a mutex.

Morgan Fouque
  • 643
  • 1
  • 7
  • 17
  • Highly related: http://stackoverflow.com/questions/22873082/is-there-any-idiomatic-explicit-use-of-mutexlock-or-unlock – NathanOliver Jun 21 '16 at 13:32

2 Answers2

47

Yes, the std::unique_lock calls unlock on the mutex in its destructor.

The benefit of this is that in case some exception is thrown, you are sure that the mutex will unlock when leaving the scope where the std::unique_lock is defined.

Dean Seo
  • 5,486
  • 3
  • 30
  • 49
gbehar
  • 1,229
  • 10
  • 10
  • 2
    So using simple mutex is not recommended, as having an exception could induce problems with the locks, which unique_lock prevents? – Morgan Fouque Jun 21 '16 at 13:39
  • 1
    If you're code inside the lock can throw an exception, then yes. If you only lock once, and unlock at the end, than std::lock_guard will also do the job, and it's simpler than std::unique_lock – gbehar Jun 21 '16 at 13:44
13

Think of it this way:

// define a mutex
std::mutex mtx;

... much later ...

void something_safe()
{

  // code in these braces is a critical section
  {
    auto lock = std::unique_lock<std::mutex>(mtx); // equivalent to mtx.lock();
    ... //protected stuff
  }  // <---- however you leave this brace, equivalent to mtx.unlock();

  ... //non-protected stuff
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • 4
    this doesn't address any of the questions asked. – Cengiz Kandemir Feb 16 '17 at 10:34
  • 2
    The edit queue for this post is full, but essentially what Richard is trying to get at is with a unique_lock you don't have to explicitly unlock the mutex - it unlocks when the unique_lock object goes out of scope. – ClydeTheGhost May 23 '17 at 17:58