Chapter 27. Preventing resource overuse by using mutex

Mutual exclusion (mutex) algorithms are used to prevent overuse of common resources.

27.1. Mutex options

Mutual exclusion (mutex) algorithms are used to prevent processes simultaneously using a common resource. A fast user-space mutex (futex) is a tool that allows a user-space thread to claim a mutex without requiring a context switch to kernel space, provided the mutex is not already held by another thread.

When you initialize a pthread_mutex_t object with the standard attributes, a private, non-recursive, non-robust, and non-priority inheritance-capable mutex is created. This object does not provide any of the benfits provided by the pthreads API and the RHEL for Real Time kernel.

To benefit from the pthreads API and the RHEL for Real Time kernel, create a pthread_mutexattr_t object. This object stores the attributes defined for the futex.

Note

The terms futex and mutex are used to describe POSIX thread (pthread) mutex constructs.

27.2. Creating a mutex attribute object

To define any additional capabilities for the mutex, create a pthread_mutexattr_t object. This object stores the defined attributes for the futex. This is a basic safety procedure that you must always perform.

Procedure

  • Create the mutex attribute object using one of the following:

    • pthread_mutex_t(my_mutex);
    • pthread_mutexattr_t(&my_mutex_attr);
    • pthread_mutexattr_init(&my_mutex_attr);

For more information about advanced mutex attributes, see Advanced mutex attributes.

27.3. Creating a mutex with standard attributes

When you initialize a pthread_mutex_t object with the standard attributes, a private, non-recursive, non-robust, and non-priority inheritance-capable mutex is created.

Procedure

  • Create a mutex object under pthreads using one of the following:

    • pthread_mutex_t(my_mutex);
    • pthread_mutex_init(&my_mutex, &my_mutex_attr);

      where &my_mutex_attr; is a mutex attribute object.

27.4. Advanced mutex attributes

The following advanced mutex attributes can be stored in a mutex attribute object:

Mutex attributes

Shared and private mutexes

Shared mutexes can be used between processes, however they can create a lot more overhead.

pthread_mutexattr_setpshared(&my_mutex_attr, PTHREAD_PROCESS_SHARED);

Real-time priority inheritance

You can avoid priority inversion problems by using priority inheritance.

pthread_mutexattr_setprotocol(&my_mutex_attr, PTHREAD_PRIO_INHERIT);

Robust mutexes

When a pthread dies, robust mutexes under the pthread are released. However, this comes with a high overhead cost. _NP in this string indicates that this option is non-POSIX or not portable.

pthread_mutexattr_setrobust_np(&my_mutex_attr, PTHREAD_MUTEX_ROBUST_NP);

Mutex initialization

Shared mutexes can be used between processes, however, they can create a lot more overhead.

pthread_mutex_init(&my_mutex_attr, &my_mutex);

27.5. Cleaning up a mutex attribute object

After the mutex has been created using the mutex attribute object, you can keep the attribute object to initialize more mutexes of the same type, or you can clean it up. The mutex is not affected in either case.

Procedure

  • Clean up the attribute object using the _destroy command.

    pthread_mutexattr_destroy(&my_mutex_attr);

    The mutex now operates as a regular pthread_mutex, and can be locked, unlocked, and destroyed as normal.

27.6. Additional resources

  • futex(7) man page
  • pthread_mutex_destroy(P) man page
  • pthread_mutexattr_setprotocol(3p) man page
  • pthread_mutexattr_setprioceiling(3p) man page