Чтение онлайн

на главную - закладки

Жанры

QNX/UNIX: Анатомия параллелизма
Шрифт:

В QNX Neutrino 6.2.1 мьютекс имеет наибольшие возможности по тонкой настройке своих параметров среди всех иных элементов синхронизации. В связи с этим поведение мьютекса очень сильно зависит от того, какие значения вы присвоите его атрибутам.

Как видите, главное отличие мьютекса от семафора заключается в том, что он хранит информацию о потоке, исполняющем код критической секции. Отсюда и важнейшие свойства мьютекса. Мьютекс нельзя разблокировать из другого потока. Если поток захватил мьютекс, то только он может его «отпустить». Используя информацию о владельце (tid потока), система может изменять в нужное время приоритет владельца для разрешения

проблемы инверсии приоритетов. Наконец, зная идентификатор потока, мьютекс может выделить ситуацию, когда поток, уже захвативший мьютекс, пытается захватить его повторно (одна из разновидностей deadlock — мертвой блокировки, когда не существует ни одного потока, способного отпустить мьютекс и разблокировать потоки, ожидающие освобождения этого мьютекса).

В ОС QNX возможен вариант работы мьютекса, не предусмотренный стандартом POSIX, — рекурсивный мьютекс. В этом режиме поток, владеющий мьютексом при повторном его захвате, не блокируется. Мьютекс только отмечает в своем внутреннем счетчике, сколько раз он был захвачен, и разблокируется только после равного количества освобождений (естественно, тем же потоком).

Все объявления относительно мьютексов находятся в заголовочном файле

<pthread.h>
, и программный код, их использующий, должен включать директиву:

#include <pthread.h>

Параметры мьютекса

Параметры мьютекса хранятся в структуре

pthread_mutexattr_t
, которая определена типом
sync_attr_t
. Эта структура должна быть, создана и определена до инициализации мьютекса, после чего может быть переопределена и использована для других объектов типа мьютекс.

Инициализация параметров

int pthread_mutexattr_init(const pthread_mutexattr_t* attr);

Функция инициализирует структуру атрибутов мьютекса, на которую указывает параметр

attr
. Тип данных
pthread_mutexattr_t
определен в файле
<pthread.h>
(производный от типа
sync_attr_t
, который в свою очередь определен в файле
<target_nto.h>
) следующим образом:

struct _sync_attr_t {

int protocol;

int flags;

int prioceiling;

int clockid; /* только для condvar */

int reserved[4];

};

После инициализации значения по умолчанию могут быть прочитаны или изменены группой функций, приведенной ниже.

Установка граничного приоритета

int pthread_mutexattr_setprioceiling(

pthread_mutexattr_t* attr, int prioceiling);

int pthread_mutexattr_getprioceiling(

const pthread_mutexattr_t* attr, int* prioceiling);

Эти функции записывают/читают значение приоритета, которое будет присваиваться потоку, захватившему мьютекс, если поле protocol структуры

pthread_mutexattr_t
установлено
в значение
PTHREAD_PRIO_PROTECT.

Этот параметр используется для реализации протокола граничного приоритета (Priority Ceiling Protocol), предлагающего альтернативный вариант защиты от инверсии приоритетов там, где наследование приоритетов может быть неэффективно или нежелательно.

Примечание

Как известно, классический случай инверсии приоритетов может возникать, когда более двух потоков разного приоритета конкурируют и разделяют один общий ресурс. В этой ситуации возможно такое стечение обстоятельств, когда низкоприоритетный поток захватывает ресурс, но позже вытесняется потоком среднего приоритета, а поток с высоким приоритетом блокируется в ожидании освобождения ресурса, захваченного низкоприоритетным потоком. Эта ситуация детально описана в соответствующей главе [4], где приводится сравнительный анализ поведения различных ОС в этой ситуации. Классическим решением этой проблемы является протокол наследования приоритетов, когда ОС распознает ситуацию подобного блокирования и автоматически повышает приоритет вытесненного потока (низкого приоритета) до уровня наивысшего приоритета из числа потоков, ожидающих освобождения ресурса. В результате поток с низким приоритетом не вытесняется, как надлежало бы в соответствии с его изначальным приоритетом, а быстро проходит критическую секцию (освобождая ее), после чего его приоритет возвращается на исходный уровень.

В ряде случаев наследование приоритетов может оказаться не самым оптимальным решением. Примером здесь может служить ситуация, когда один высокоприоритетный поток разделяет много ресурсов с низкоприоритетными потоками — по одному ресурсу на каждый поток. В такой ситуации может возникнуть положение, когда много низкоприоритетных потоков (вытесненных) выстроятся перед высокоприоритетным. Но тогда длинный ряд последовательных операций вытеснения («поштучно») и наследования приоритетов блокирующих потоков может привести к тому, что не хватит времени до окончания критического срока выполнения потока высокого приоритета, пока ОС будет анализировать ситуацию и последовательно проводить протокол наследования приоритетов.

Именно для таких ситуаций и предназначен протокол граничного приоритета. В соответствии с этим протоколом примитив синхронизации (в нашем рассмотрении это мьютекс) наделяется собственным фиксированным приоритетом, а приоритет любого потока, захватившего этот мьютекс, поднимается до предустановленного граничного уровня приоритета мьютекса.

Определение протокола защиты от инверсии приоритетов

int pthread_mutexattr_setprotocol(

pthread_mutexattr_t* attr, int protocol);

int pthread_mutexattr_getprotocol(

pthread_mutexattr_t* attr, int* protocol);

Эти функции устанавливают/считывают протокол, который реализуется мьютексом для защиты от инверсии приоритетов. Переменная

protocol
может принимать следующие значения:

PTHREAD_PRIO_INHERIT
(значение по умолчанию) — определяет, что для воспрепятствования возникновению инверсии приоритетов будет использоваться протокол наследования приоритетов.

Поделиться:
Популярные книги

Газлайтер. Том 8

Володин Григорий
8. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 8

На Ларэде

Кронос Александр
3. Лэрн
Фантастика:
фэнтези
героическая фантастика
стимпанк
5.00
рейтинг книги
На Ларэде

Охота на попаданку. Бракованная жена

Герр Ольга
Любовные романы:
любовно-фантастические романы
5.60
рейтинг книги
Охота на попаданку. Бракованная жена

Кай из рода красных драконов

Бэд Кристиан
1. Красная кость
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Кай из рода красных драконов

Хозяйка Проклятой Пустоши. Книга 2

Белецкая Наталья
2. Хозяйка Проклятой Пустоши
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Хозяйка Проклятой Пустоши. Книга 2

Безумный Макс. Поручик Империи

Ланцов Михаил Алексеевич
1. Безумный Макс
Фантастика:
героическая фантастика
альтернативная история
7.64
рейтинг книги
Безумный Макс. Поручик Империи

Потусторонний. Книга 2

Погуляй Юрий Александрович
2. Господин Артемьев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Потусторонний. Книга 2

Чапаев и пустота

Пелевин Виктор Олегович
Проза:
современная проза
8.39
рейтинг книги
Чапаев и пустота

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

Лютая

Шёпот Светлана Богдановна
Любовные романы:
любовно-фантастические романы
6.40
рейтинг книги
Лютая

Ведьмак (большой сборник)

Сапковский Анджей
Ведьмак
Фантастика:
фэнтези
9.29
рейтинг книги
Ведьмак (большой сборник)

Наследие Маозари 4

Панежин Евгений
4. Наследие Маозари
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Наследие Маозари 4

Ученик

Губарев Алексей
1. Тай Фун
Фантастика:
фэнтези
5.00
рейтинг книги
Ученик

Начальник милиции. Книга 5

Дамиров Рафаэль
5. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции. Книга 5