The mutexes and locks here have relatively spartan interfaces that are designed for high performance. The interfaces enforce the scoped locking pattern, which is widely used in C++ libraries because:
There are two parts to the pattern: a mutex object, for which construction of a lock object acquires a lock on the mutex and destruction of the lock object releases the lock. Here's an example:
{ // Construction of myLock acquires lock on myMutex M::scoped_lock myLock( myMutex ); // ... actions to be performed while holding the lock ... // Destruction of myLock releases lock on myMutex }
If the actions throw an exception, the lock is automatically released as the block is exited.
The following table shows the requirements for the Mutex concept for a mutex type M
Mutex Concept
Pseudo-Signature |
Semantics |
---|---|
M() |
Construct unlocked mutex. |
~M() |
Destroy unlocked mutex. |
typename M::scoped_lock |
Corresponding scoped-lock type. |
M::scoped_lock() |
Construct lock without acquiring mutex. |
M::scoped_lock(M&) |
Construct lock and acquire lock on mutex. |
M::~scoped_lock() |
Release lock (if acquired). |
M::scoped_lock::acquire(M&) |
Acquire lock on mutex. |
bool M::scoped_lock::try_acquire(M&) |
Try to acquire lock on mutex. Return true if lock acquired, false otherwise. |
M::scoped_lock::release() |
Release lock. |
static const bool M::is_rw_mutex |
True if mutex is reader-writer mutex; false otherwise. |
static const bool M::is_recursive_mutex |
True if mutex is recursive mutex; false otherwise. |
static const bool M::is_fair_mutex |
True if mutex is fair; false otherwise. |
The following table summarizes the classes that model the Mutex concept.
Mutexes that Model the Mutex Concept
|
Scalable |
Fair |
Reentrant |
Long Wait |
Size |
---|---|---|---|---|---|
mutex |
OS dependent |
OS dependent |
No |
Blocks |
>=3 words |
recursive_mutex |
OS dependent |
OS dependent |
Yes |
Blocks |
>=3 words |
spin_mutex |
No |
No |
No |
Yields |
1 byte |
speculative_spin_mutex |
No |
No |
No |
Yields |
2 cache lines |
queuing_mutex |
Yes |
Yes |
No |
Yields |
1 word |
spin_rw_mutex |
No |
No |
No |
Yields |
1 word |
queuing_rw_mutex |
Yes |
Yes |
No |
Yields |
1 word |
null_mutex |
- |
Yes |
Yes |
- |
empty |
null_rw_mutex |
- |
Yes |
Yes |
- |
empty |
See the Intel® Threading Building Blocks Tutorial for a discussion of the mutex properties and the rationale for null mutexes.
Classes mutex, recursive_mutex, spin_mutex, and spin_rw_mutex support the C++11 interfaces described in the following table.
C++11 Methods Available for Some Mutexes.
Pseudo-Signature |
Semantics |
---|---|
void M::lock() |
Acquire lock. |
bool M::try_lock() |
Try to acquire lock on mutex. Return true if lock acquired, false otherwise. |
void M::unlock() |
Release lock. |
class lock_guard<M> |
See Section C++11 Synchronization |
class unique_lock<M> |
Classes mutex and recursive mutex also provide the C++11 idiom for accessing their underlying OS handles, as described in the following table.
Native handle interface (M is mutex or recursive_mutex).
Pseudo-Signature |
Semantics |
---|---|
M::native_handle_type |
Native handle type. For Windows* operating system, LPCRITICAL_SECTION is the Native handle type. For all other operating system, it is (pthread_mutex*). |
native_handle_type M::native_handle() |
Get underlying native handle of mutex M. |
As an extension to C++11, class spin_rw_mutex also has methods read_lock() and try_read_lock() for corresponding operations that acquire reader locks.