Службы синхронизации
В ОС QNX Neutrino используются POSIX-примитивы для синхронизации на уровне потоков. Некоторые из этих примитивов могут применяться для потоков в разных процессах. К службам синхронизации относятся следующие объекты
служба синхронизациии | межзадачная поддержка | сетевая поддержка |
Мьютекс | да | нет |
Условная переменная | да | нет |
Барьер | нет | нет |
Ждущая блокировка | нет | нет |
Блокировка чтения/записи | да | нет |
Семафор | да | да(только для именованных |
FIFO-планирование | да | нет |
Отправка/получение/ответ | да | да |
Атомарная операция | да | нет |
Приведенные примитивы синхронизации реализуются непосредственно ядром, за исключением: · барьеров, ждущих блокировок (sleepon locks) и блокировок чтения/записи (которые основаны на мьютексах и условных переменных); · атомарных операций (которые либо реализуются непосредственно процессором, либо эмулируются ядром). |
Блокировки взаимного исключения (мьютексы)
Наиболее простыми из служб синхронизации являются мьютексы. Мьютекс (от англ. mutex — mutual exclusion lock) служит для обеспечения монопольного доступа к данным, которые совместно используются несколькими потоками. Операциями захвата мьютекса (с помощью функции pthread_mutex_lock()) и освобождения мьютекса (с помощью функции pthread_mutex_unlock()) обычно обрамляются участки кода, который обращается к совместно используемым данным (обычно это критическая секция кода).
В каждый момент времени мьютекс может быть захвачен только одним потоком. Потоки, которые пытаются захватить уже захваченный мьютекс, блокируются до тех пор, пока этот мьютекс не освобождается. Когда поток освобождает мьютекс, поток с наивысшим приоритетом, который ожидает возможности захватить мьютекс, будет разблокирован и станет новым владельцем мьютекса. Таким образом, потоки обрабатывают критическую секцию кода в порядке своих приоритетов.
В большинстве процессоров захват мьютекса не требует обращения к ядру. Это достигается благодаря операции "сравнить и переставить" (compare-and-swap opcode) в семействе х86, а также посредством условных инструкций "загрузить/сохранить" на большинстве процессоров семейства RISC.
При захвате мьютекса передача управления коду ядра происходит только при условии, что мьютекс уже захвачен и поток может быть включен в список блокированных потоков. Управление передается коду ядра также при освобождении мьютекса, если другие потоки ожидают разблокирования на этом мьютексе. Это позволяет выполнять захват и освобождение критических секций с очень высокой скоростью. Таким образом, действие ОС сводится всего лишь к управлению приоритетами.
Для определения текущего состояния мьютекса используется специальная неблокирующая функция pthread_mutex_trylock().
Дата добавления: 2017-01-29; просмотров: 512;