Intel TBB Simple Mutex - Example

The following examples shows basic usage of a Intel TBB 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 Intel TBB 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 Intel TBB 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.

Intel TBB 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.

For more complete information about compiler optimizations, see our Optimization Notice.