What's the difference between “mutex” and “loc

2020-05-18 17:08发布

问题:

I am very confused about the difference between a lock and mutex. In Boost docs, it says,

Lock Types

  • Class template lock_guard
  • Class template unique_lock
  • Class template shared_lock
  • Class template upgrade_lock
  • Class template upgrade_to_unique_lock
  • Mutex-specific class scoped_try_lock

Mutex Types

  • Class mutex
  • Typedef try_mutex
  • Class timed_mutex
  • Class recursive_mutex
  • Typedef recursive_try_mutex
  • Class recursive_timed_mutex
  • Class shared_mutex

In another article, I see functions like this,

boost::shared_mutex _access;
void reader()
{
  boost::shared_lock< boost::shared_mutex > lock(_access);
  // do work here, without anyone having exclusive access
}    
void conditional_writer()
{
  boost::upgrade_lock< boost::shared_mutex > lock(_access);
  // do work here, without anyone having exclusive access

  if (something) {
    boost::upgrade_to_unique_lock< boost::shared_mutex > uniqueLock(lock);
    // do work here, but now you have exclusive access
  }
  // do more work here, without anyone having exclusive access
}

Updated questions

  1. Can anyone offer some clarification between the "mutex" and "lock"?
  2. Is it necessary to create a shared_lock for a shared_mutex? What happen if I create a unique_lock for a shared_mutex?
  3. Or if I create a shared_lock for a mutex, does it mean the mutex can not be shared among multiple threads?

回答1:

A mutex is a synchronization object. You acquire a lock on a mutex at the beginning of a section of code, and release it at the end, in order to ensure that no other thread is accessing the same data at the same time. A mutex typically has a lifetime equal to that of the data it is protecting, and that one mutex is accessed by multiple threads.

A lock object is an object that encapsulates that lock. When the object is constructed it acquires the lock on the mutex. When it is destructed the lock is released. You typically create a new lock object for every access to the shared data.



回答2:

A mutex is an object which can be locked. A lock is the object which maintains the lock. To create a lock, you need to pass it a mutex.



回答3:

Locks can provide mutual exclusion but not condition synchronization.Unlike a semaphore, a lock has an owner, and ownership plays an important role in the behavior of a lock

example -

class lockableObject { public void F() {
mutex.lock(); ...; mutex.unlock();
}
public void G() {
mutex.lock(); ...; F(); ...; mutex.unlock();
}
private mutexLock mutex; }
// method G() calls method F()

Lock mutex in class lockableObject is used to turn methods F() and G() into critical sections. Thus, only one thread at a time can execute inside a method of a lockableObject. When a thread calls method G(), the mutex is locked. When method G() calls method F(), mutex.lock() is executed in F(), but the calling thread is not blocked since it already owns mutex. If mutex were a binary semaphore instead of a lock, the call from G() to F() would block the calling thread when mutex.P() was executed in F(). (Recall that comple- tions of P() and V() operations on a binary semaphore must alternate.) This would create a deadlock since no other threads would be able execute inside F() or G().

These are differences between locks and binary semaphores: 1 For a binary semaphore,if two calls are made toP()without any intervening call to V(), the second call will block. But a thread that owns a lock and requests ownership again is not blocked. (Beware of the fact that locks are not always recursive, so check the documentation before using a lock.) 2 The owner for successive calls to lock() and unlock() must be the same thread. But successive calls to P () and V () can be made by different threads.