4. Примитивы синхронизации

4. Примитивы синхронизации

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

Примечание

К сожалению, и техническая документация QNX [8], и фундаментальная книга Р. Кертена [1] написаны по одной схеме:[35] все, что касается примитивов синхронизации, введенных более поздними расширениями POSIX (барьеры, жесткая блокировка (sleepon), спинлок, блокировки чтения-записи), описывается детально и сопровождается обстоятельными примерами кода, а вот базовые понятия, такие как pthread_mutex_t, sem_t (да и pthread_cond_t, по существу), описаны лишь качественно, «на пальцах», в иллюстративных рассказах об алгоритме пользования ванной комнатой и кухней (термин bathroom встречается намного чаще, чем pthread_mutex_t). Мы попытаемся по возможности компенсировать этот перекос.

Хотелось бы обратить внимание на интересный факт. В POSIX-варианте API QNX представлен большой набор разнообразных средств синхронизации: мьютексы, условные переменные, семафоры, барьеры, блокировки чтения/записи, ждущие блокировки, спинлоки. Однако в родном native API QNX из всего этого многообразия мы видим всего три элемента синхронизации: мьютекс, семафор и условная переменная. И это при том, что условная переменная не является самостоятельным средством синхронизации и применяется как расширение функциональных возможностей мьютекса!

Это означает, что все многообразие средств синхронизации, предоставляемое в POSIX API QNX, строится исключительно с применением этих минимальных средств синхронизации. Действительно, анализ заголовочных файлов системы показывает, что все дополнительные средства синхронизации, появляющиеся в POSIX API, строятся с использованием только мьютекса и условной переменной. Можно сказать, что пара мыотекс-условная переменная с одной стороны и семафор с другой являются независимыми базисами, каждый из которых позволяет построить практически любой, сколь угодно специфический элемент синхронизации, удовлетворяющий потребностям, которые могут возникнуть при построении вашей системы. Мы проиллюстрируем эту мысль позже, при рассмотрении особенностей применения мьютексов.

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

Мы постараемся проиллюстрировать эту идею примерами использования базовых средств синхронизации в качестве «конструктора» при построении более сложных. Три базовых элемента синхронизации ОС QNX — мьютекс, условная переменная и семафор — реализуются на уровне микроядра системы и создаются вызовом системной функции:

SyncTypeCreate(unsigned type, sync_t* sync, const struct _sync_attr_t* attr);

Здесь type может принимать значения:

_NTO_SYNC_MUTEX_FREE — для создания мьютекса;

_NTO_SYNC_SEM — для создания семафора;

_NTO_SYNC_COND — для создания условной переменной.

Стоит обратить внимание на два важных факта. Во-первых, типы мьютекса (pthread_mutex_t), условной переменной (pthread_cond_t) и семафора (sem_t) являются псевдонимами типа sync_t. А во-вторых, типы атрибутов этих объектов также являются псевдонимами одного-единственного типа — sync_attr_t, содержащего поле protocol, значение которого определяет, каким способом ОС будет варьировать приоритеты во избежание их инверсии.

В соответствии с документацией QNX 6.2.1 это поле присутствует у параметров всех трех базовых объектов синхронизации, но доступно оно только для переопределения мьютексов. По умолчанию (например, когда вместо attr передается NULL) поле protocol принимает значение PTHREAD_PRIO_INHERIT. Это означает, что ОС будет использовать протокол наследования приоритетов для предотвращения инверсии.

Таким образом, все примитивы синхронизации QNX в теории могут учитывать эффект инверсии приоритетов. Однако на практике важны следующие два вопроса: возможно ли в принципе возникновение ситуации инверсии приоритетов для данного типа примитивов, и если да, то актуально ли для данного типа примитивов препятствовать возникновению инверсии (в качестве иллюстрации этого утверждения можно рассмотреть примитив типа барьер).

Тесты [4] показывают, что только для мьютексов наследованием приоритетов (или альтернативными протоколами) однозначно предотвращается возникновение инверсии приоритетов. По-видимому, в первую очередь это связано с тем, что сама по себе инверсия может возникнуть именно в тех случаях, когда из всех элементов синхронизации необходимо использовать именно мьютекс или что-либо из его наследников (например, блокировки чтения-записи).

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Примитивы, определённые в библиотеке

Из книги Руководство по стандартной библиотеке шаблонов (STL) автора Ли Менг

Примитивы, определённые в библиотеке Чтобы упростить задачу определения iterator_category, value_type и distance_type для определяемых пользователем итераторов, библиотека обеспечивает следующие предопределённые классы и функции:// iterator tags (теги итераторов)struct input_iterator_tag {};struct output_iterator_tag


Примитивы управления памятью (Memory Handling Primitives)

Из книги AutoCAD 2009 автора Орлов Андрей Александрович

Примитивы управления памятью (Memory Handling Primitives) Чтобы получать типичный указатель на неинициализированный буфер памяти данного размера, определена следующая функция:template ‹class T›inline T* allocate(ptrdiff_t n, Т*); // n ›= 0Размер (в байтах) распределённого буфера - не меньше n*sizeof(T).Для


Поверхностные примитивы

Из книги Введение в OpenGL автора Компьютеры Автор неизвестен -

Поверхностные примитивы Стандартные трехмерные примитивы в программе AutoCAD можно создать несколькими способами. Первый способ – использование команды 3D. После ее запуска в командной строке появится запрос: Enter an option [Box/Cone/DIsh/DOme/Mesh/Pyramid/Sphere/Torus/Wedge]: Выбрав один из параметров


Вершины и примитивы

Из книги AutoCAD 2010 автора Орлов Андрей Александрович

Вершины и примитивы Определение атрибутов вершины Под вершиной понимается точка в трехмерном пространстве, координаты которой можно задавать следующим образом:void glVertex[2 3 4][s i f d](type coords)void glVertex[2 3 4][s i f d]v(type *coords)Координаты точки задаются максимум четырьмя значениями: x, y,


Стандартные геометрические примитивы

Из книги Системное программирование в среде Windows автора Харт Джонсон М

Стандартные геометрические примитивы Рассмотрим стандартные команды построения примитивов, которые реализованы в библиотеках GLU и GLUT.Как уже было сказано, чтобы построить примитив из библиотеки GLU, надо сначала создать указатель на quadric- объект с помощью команды


Поверхностные примитивы

Из книги TCP/IP Архитектура, протоколы, реализация (включая IP версии 6 и IP Security) автора Фейт Сидни М

Поверхностные примитивы Стандартные трехмерные примитивы в программе AutoCAD можно создать несколькими способами. Первый способ – использование команды 3D. После ее запуска в командной строке появится запрос:Enter an option[Box/Cone/DIsh/DOme/Mesh/Pyramid/Sphere/Torus/Wedge]:Выбрав один из параметров


Необходимость в синхронизации потоков

Из книги Справочник по PHP автора

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


13.9.1 Сигнал синхронизации

Из книги Разработка приложений в среде Linux. Второе издание автора Джонсон Майкл К.

13.9.1 Сигнал синхронизации Для некоторых функций (например, Interrupt Process) включение команды в общий поток данных не приводит к нужным результатам. Когда реальный терминал посылает сигнал прерывания, хост операционной системы получает этот сигнал сразу и быстро останавливает


Графические примитивы

Из книги КОМПАС-3D для студентов и школьников. Черчение, информатика, геометрия автора Большаков Владимир


10.4. Примитивы процессов

Из книги Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform автора Кёртен Роб

10.4. Примитивы процессов Несмотря на относительно длинную дискуссию, необходимую для описания процесса, создание и уничтожение процессов в Linux достаточно


1.2. Создание изображений. Графические примитивы

Из книги Операционная система UNIX автора Робачевский Андрей М.

1.2. Создание изображений. Графические примитивы Команды создания графических примитивов позволяют строить единые и неделимые объекты различными типами линий и разными цветами.Точка, как правило, является вспомогательным средством для маркировки и последующего


Дополнительно о синхронизации

Из книги Установка, настройка и восстановление Windows 7 на 100% автора Ватаманюк Александр Иванович

Дополнительно о синхронизации Мы уже обсудили:• мутексы;• семафоры;• барьеры.Давайте теперь завершим нашу дискуссию о синхронизации, обсудив следующее:• блокировки чтения/записи (reader/writer locks);• ждущие блокировки (sleepons);• условные переменные (condition


Примитивы DLPI

Из книги Разработка ядра Linux автора Лав Роберт

Примитивы DLPI Как и в случае предоставления транспортных услуг, обмен данными между пользователем и поставщиком происходит в виде сообщений, несущих примитивы DLPI. Ниже рассмотрены некоторые из этих примитивов, относящиеся к режиму передачи без предварительного


Центр синхронизации

Из книги Описание языка PascalABC.NET автора Коллектив РуБоард

Центр синхронизации С помощью этого компонента вы можете синхронизировать данные своего мобильного телефона или любого другого устройства, подключенного к компьютеру, с данными на компьютере. Кроме того, аналогичные действия можно выполнять и по отношению к данным,


Резюмирование по синхронизации

Из книги автора

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


Графические примитивы

Из книги автора

Графические примитивы Графические примитивы представляют собой процедуры, осуществляющие рисование в графическом окне. Рисование осуществляется текущим пером (линии), текущей кистью (заливка замкнутых областей) и текущим шрифтом (вывод строк). procedure SetPixel(x,y: integer; c: Color);