QNX/UNIX: Анатомия параллелизма
Шрифт:
Как и обычно, внешнее различие (для программиста) основной формы
•
•
Возможны следующие коды ошибок, возвращаемые этими вызовами:
Для того чтобы получить работающий пример использования этой возможности, возьмите любой из приводившихся выше примеров, разнесите процессы по сетевым узлам и определите «целеуказание» в процессе-отправителе.
Простейшим примером и демонстрацией удаленной реакции в сети может быть следующая последовательность действий:
• Производим запуск задачи на удаленномузле, например:
• После чего, выполнив ряд операций в запущенной программе, прекращаем ее работу по [Ctrl+C] с локального терминала.
Интересно оценить далеко идущие последствия этого «маленького» расширения стандартной POSIX-схемы работы с сигналами:
• На технике «сетевых сигналов» может быть построена целая система уведомлений сетевых составляющих компонент единой программной прикладной системы.
• Именно «уведомлений» (но не синхронизации с наследованием приоритетов, влияющей на общую систему диспетчеризации составляющих частей и т.п.): посылка сигнала является неблокирующей операцией (не требует ответа), а прием сигнала не сопровождается наследованием (или любым изменением) приоритетов.
• Такое «сигнальное» взаимодействие, записанное в формальной POSIX-семантике (но, по сути, осуществляющее механизмы, далеко выходящие за POSIX), может оказаться гораздо проще в записи и понимании, чем при использовании низкоуровневых механизмов обмена сообщениями (пульсами).
4. Примитивы синхронизации
ОС QNX Neutrino предоставляет широкий набор элементов синхронизации выполнения потоков, как в рамках одного процесса, так и разных. Это практически полный спектр примитивов, описываемых как базовым стандартом POSIX, так и всеми его расширениями реального времени. Тем не менее при работе со всеми этими примитивами не покидает ощущение, что некоторые из них являются органичными для самой ОС (мьютекс, условная переменная), в то время как другие — достаточно громоздкая надстройка над базовыми механизмами, реализуемая, главным образом, в угоду POSIX.
К сожалению, и техническая документация QNX [8], и фундаментальная книга Р. Кертена [1] написаны по одной схеме: [35] все, что касается примитивов синхронизации, введенных более поздними расширениями POSIX (барьеры, жесткая блокировка (sleepon), спинлок, блокировки чтения-записи), описывается детально и сопровождается обстоятельными примерами кода, а вот базовые понятия, такие как
35
И здесь вопрос не в плагиате. Известно, что Р. Кертен долгое время сотрудничал с QSSL именно по части написания документации, поэтому она во многом следует его манере изложения, хотя более поздняя книга Р. Кертена [1] изложена заметно доходчивее.
Хотелось бы обратить внимание на интересный факт. В POSIX-варианте API QNX представлен большой набор разнообразных средств синхронизации: мьютексы, условные переменные, семафоры, барьеры, блокировки чтения/записи, ждущие блокировки, спинлоки. Однако в родном native API QNX из всего этого многообразия мы видим всего три элемента синхронизации: мьютекс, семафор и условная переменная. И это при том, что условная переменная не является самостоятельным средством синхронизации и применяется как расширение функциональных возможностей мьютекса!
Это означает, что все многообразие средств синхронизации, предоставляемое в POSIX API QNX, строится исключительно с применением этих минимальных средств синхронизации. Действительно, анализ заголовочных файлов системы показывает, что все дополнительные средства синхронизации, появляющиеся в POSIX API, строятся с использованием толькомьютекса и условной переменной. Можно сказать, что пара мыотекс-условная переменная с одной стороны и семафор с другой являются независимыми базисами, каждый из которых позволяет построить практически любой, сколь угодно специфический элемент синхронизации, удовлетворяющий потребностям, которые могут возникнуть при построении вашей системы. Мы проиллюстрируем эту мысль позже, при рассмотрении особенностей применения мьютексов.
Независимо от того, какой набор элементов синхронизации окажется предпочтительным для разрабатываемой вами системы, важным является тот факт, что в случае, если предлагаемые системой средства синхронизации по каким-то причинам вас не устраивают, то ничто не мешает разработать собственные средства синхронизации, используя тот или иной базис или даже их комбинацию. И эффективность полученного нового средства синхронизации будет зависеть только от вас.
Мы постараемся проиллюстрировать эту идею примерами использования базовых средств синхронизации в качестве «конструктора» при построении более сложных. Три базовых элемента синхронизации ОС QNX — мьютекс, условная переменная и семафор — реализуются на уровне микроядра системы и создаются вызовом системной функции:
Здесь
Стоит обратить внимание на два важных факта. Во-первых, типы мьютекса (