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.