Книга: Programming with POSIX® Threads

5.5.5 Priority-aware mutexes

#if defined (_POSIX_THREAD_PRIO_PROTECT)

|| defined (_POSIX_THREAD_PRIO_INHERIT)

int pthread_mutexattr_getprotocol (

const pthread_mutexattr_t *attr, int *protocol);

int pthread_mutexattr_setprotocol (

pthread_mutexattr_t *attr, int protocol);

#endif

#ifdef _POSIX_THREAD_PRIO_PROTECT

int pthread_mutexattr_getprioceiling (

const pthread_attr_t *attr, int *prioceiling);

int pthread_mutexattr_setprioceiling (

pthread_mutexattr_t *attr, int prioceiling);

int pthread_mutex_getprioceiling (

const pthread_mutex_t *mutex, int *prioceiling);

int pthread_mutex_setprioceiling (

pthread_mutex_t *mutex,

int prioceiling, int *old_ceiling);

#endif

Pthreads provides several special mutex attributes that can help to avoid priority inversion deadlocks. Locking, or waiting for, a mutex with one of these attributes may change the priority of the thread — or the priority of other threads— to ensure that the thread that owns the mutex cannot be preempted by another thread that needs to lock the same mutex.

These mutex attributes may not be supported by your implementation of Pthreads, because they are optional features. If your code needs to function with or without these options, you can conditionally compile references based on the feature test macros _POSIX_THREAD_PRIO_PROTECT or _POSIX_THREAD_PRIO_ INHERIT, defined in <unistd.h>, or you can call sysconf during program execution to check for SC_THREAD_PRIO_PROTECT or SC_THREAD_PRIO_INHERIT.

Once you've created a mutex using one of these attributes, you can lock and unlock the mutex exactly like any other mutex. As a consequence, you can easily convert any mutex you create by changing the code that initializes the mutex. (You must call pthread_mutex_init, however, because you cannot statically initialize a mutex with nondefault attributes.)

"Priority ceiling" protocol means that while a thread owns the mutex, it runs at the specified priority.

If your system defines _POSIX_THREAD_PRIO_PROTECT then it supports the protocol and prioceiling attributes. You set the protocol attribute by calling pthread_mutexattr_setprotocol. If you set the protocol attribute to the value PTHREAD_PRIO_PROTECT, then you can also specify the priority ceiling for mutexes created using the attributes object by setting the prioceiling attribute.

You set the prioceiling attribute by calling the function pthread_mutexattr_ setprioceiling. When any thread locks a mutex defined with such an attributes object, the thread's priority will be set to the priority ceiling of the mutex, unless the thread's priority is already the same or higher. Note that locking the mutex in a thread running at a priority above the priority ceiling of the mutex breaks the protocol, removing the protection against priority inversion.

"Priority inheritance" means that when a thread waits on a mutex owned by a lower-priority thread,the priority of the owner is increased to that of the waiter.

If your system defines _POSIX_THREAD_PRIO_INHERIT then it supports the protocol attribute. If you set the protocol attribute to the value PTHREAD_PRIO_ INHERIT, then no thread holding the mutex can be preempted by another thread with a priority lower than that of any thread waiting for the mutex. When any thread attempts to lock the mutex while a lower-priority thread holds the mutex, the priority of the thread currently holding the mutex will be raised to the priority of the waiter as long as it owns the mutex.

If your system does not define either _POSIX_THREAD_PRIO_PROTECT or _POSIX_ THREAD_PRIO_INHERIT then the protocol attribute may not be defined. The default value of the protocol attribute (or the effective value ifthe attribute isn't defined) is POSIX_PRIO_NONE, which means that thread priorities are not modified by the act of locking (or waiting for) a mutex.

Оглавление книги

Оглавление статьи/книги

Генерация: 1.326. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз