Visible to Intel only — GUID: GUID-D98B389E-61B9-414A-9450-D28EF9F61A95
Visible to Intel only — GUID: GUID-D98B389E-61B9-414A-9450-D28EF9F61A95
Intel® oneAPI Threading Building Blocks (oneTBB) Simple Mutex - Example
The following examples shows basic usage of a Intel® oneAPI Threading Building Blocks (oneTBB) mutex to protect a shared variable named count using simple mutexes and scoped locks:
Simple Mutex Example
#include <tbb/mutex.h> int count; tbb::mutex countMutex; int IncrementCount() { int result; // Add oneTBB mutex countMutex.lock(); // Implements ANNOTATE_LOCK_ACQUIRE() result = count++; // Save result until after unlock countMutex.unlock(); // Implements ANNOTATE_LOCK_RELEASE() return result; }
The semantics of countMutex.lock() and unlock() on countMutex correspond directly to the annotations ANNOTATE_LOCK_ACQUIRE() and ANNOTATE_LOCK_RELEASE(). However, it is generally better to use the scoped locking pattern.
Scoped Lock Example
With a scoped lock, you construct a temporary scoped_lock object that represents acquisition of a lock. Destruction of the scoped_lock object releases the lock on the mutex.
The following code shows the previous example rewritten using scoped locking:
#include <tbb/mutex.h> int count; tbb::mutex countMutex; int IncrementCount() { int result; { // Add oneTBB scoped lock at location of ANNOTATE_LOCK annotations tbb::mutex::scoped_lock lock(countMutex); // Implements ANNOTATE_LOCK_ACQUIRE() result = count++; // Implicit ANNOTATE_LOCK_RELEASE() when leaving the scope below. } // scoped lock is automatically released here return result; }
The scoped_lock pattern is preferred because it releases the lock no matter how control leaves the block. The scoped lock is released when destruction of the scoped_lock object occurs. In particular, it releases the lock even when control leaves because an exception was thrown.
oneTBB also has a tbb::atomic template class that can be used in simple cases such as managing a shared integer variable. Check the Related Information for details.