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 Copy linkLink copied to clipboard!
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 by 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.
10.1.1. Standard mutexes Copy linkLink copied to clipboard!
The real-time standard mutexes are private, non-recursive, non-robust, and non-priority inheritance capable mutexes. Initializing a pthread_mutex_t by using pthread_mutex_init(&my_mutex, &my_mutex_attr) creates a standard mutex. When using the standard mutex type, your application might not benefit from the advantages provided by the pthreads API and the RHEL for Real Time kernel.
10.1.2. Advanced mutexes Copy linkLink copied to clipboard!
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, by 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.
For more information, see the futex(7) and pthread_mutex_destroy(P) man pages on your system.
10.2. Barriers Copy linkLink copied to clipboard!
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
stopandpassstate 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 Copy linkLink copied to clipboard!
In real-time, condition variables (condvar) is a POSIX thread construct that waits for a particular condition to be achieved before proceeding. The signaled condition relates to the state of data that the thread shares with another thread. For example, a condvar can signal a data entry into a processing queue. By 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 Copy linkLink copied to clipboard!
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 |
For more information, see the futex(7) man page on your system.
10.5. Thread synchronization functions Copy linkLink copied to clipboard!
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 |