Chapter 10. Thread synchronization mechanisms in RHEL for Real Time
In real-time, when two or more threads need access to a shared resource at the same time, the threads coordinate using the thread synchronization mechanism. Thread synchronization ensures that only one thread uses the shared resource at a time. The three thread synchronization mechanisms used on Linux: Mutexes, Barriers, and Condition variables (condvars
).
10.1. Mutexes
Mutex derives from the terms mutual exclusion. The mutual exclusion object synchronizes access to a resource. It is a mechanism that ensures only one thread can acquire a mutex at a time.
The mutex
algorithm creates a serial access to each section of code, so that only one thread executes the code at any one time. Mutexes are created using an attribute object known as the mutex
attribute object. It is an abstract object, which contains several attributes that depends on the POSIX options you choose to implement. The attribute object is defined with the pthread_mutex_t
variable. The object stores the attributes defined for the mutex. The pthread_mutex_init(&my_mutex, &my_mutex_attr)
, pthread_mutexattr_setrobust()
and pthread_mutexattr_getrobust()
functions return 0, when successful. On error, they return the error number.
In real-time, you can either retain the attribute object to initialize more mutexes of the same type or you can clean up (destroy) the attribute object. The mutex is not affected in either case. Mutexes include the standard and advanced type of mutexes.
Standard mutexes
The real-time standard mutexes are private, non-recursive, non-robust, and non-priority inheritance capable mutexes. Initializing a pthread_mutex_t
using pthread_mutex_init(&my_mutex, &my_mutex_attr)
creates a standard mutex. When using the standard mutex type, your application may not benefit from the advantages provided by the pthreads
API and the RHEL for Real Time kernel.
Advanced mutexes
Mutexes defined with additional capabilities are called advanced mutexes. Advanced capabilities include priority inheritance, robust behavior of a mutex, and shared and private mutexes. For example, for robust mutexes, initializing the pthread_mutexattr_setrobust()
function, sets the robust attribute. Similarly, using the attribute PTHREAD_PROCESS_SHARED
, allows any thread to operate on the mutex, provided the thread has access to its allocated memory. The attribute PTHREAD_PROCESS_PRIVATE
sets a private mutex.
A non-robust mutex does not release automatically and stays locked until you manually release it.
Additional resources
-
futex(7)
man page on your system -
pthread_mutex_destroy(P)
man page on your system
10.2. Barriers
Barriers operate in a very different way when compared to other thread synchronization methods. The barriers define a point in the code where all active threads stop until all threads and processes reach this barrier. Barriers are used in situations when a running application needs to ensure that all threads have completed specific tasks before execution can continue.
The barrier mutex in real-time, take following two variables:
-
The first variable records the
stop
andpass
state of the barrier. - The second variable records the total number of threads that enter the barrier.
The barrier sets the state to pass
only when the specified number of threads reach the defined barrier. When the barrier state is set to pass
, the threads and processes proceed further. The pthread_barrier_init()
function allocates the required resources to use the defined barrier and initializes it with the attributes referenced by the attr
attribute object.
The pthread_barrier_init()
and pthread_barrier_destroy()
functions return the zero value, when successful. On error, they return an error number.
10.3. Condition variables
In real-time, condition variables (condvar
) is a POSIX thread construct that waits for a particular condition to be achieved before proceeding. In general, the signaled condition relates to the state of data that the thread shares with another thread. For example, a condvar
can be used to signal a data entry into a processing queue and a thread waiting to process that data from the queue. Using the pthread_cond_init()
function, you can initialize a condition variable.
The pthread_cond_init()
, pthread_cond_wait()
, and pthread_cond_signal()
functions return the zero value, when successful. On error, it returns the error number.
10.4. Mutex classes
The mentioned mutex options provides guidance on the mutex classes to consider when writing or porting an application.
Advanced mutexes | Description |
---|---|
Shared mutexes |
Defines shared access for multiple threads to acquire a mutex at a given time. Shared mutexes can create latency. The attribute is |
Private mutexes |
Ensures that only the threads created within the same process can access the mutex. The attribute is |
Real-time priority inheritance |
Sets the priority level of the lower priority task higher above a current higher priority task. When the task completes, it releases the resource and the task drops back to its original priority permitting the higher priority task to run. The attribute is |
Robust mutexes |
Sets the robust mutexes to release automatically when the owning thread would stop. The value substring |
Additional resources
-
futex(7)
man page on your system
10.5. Thread synchronization functions
The mentioned list of function types and the description provides information on the functions to use for thread synchronization mechanisms for the real-time kernel.
Function | Description |
---|---|
|
Initiates a mutex with attributes specified by |
|
Destroys the specified mutex object. You can re-initialize with |
|
Specifies the |
|
Queries the |
|
Allocates the required resources to use and initialize the barrier with attribute object |
|
Initializes a condition variable. The |
|
Blocks a thread execution until it receives a signal from another thread. In addition, a call to this function also releases the associated lock on mutex before blocking. The argument |
|
Unblocks at least one of the threads that are blocked on a specified condition variable. The argument |