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

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

Жанры

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

Кёртен Роб

Шрифт:
Встраиваемость

В QNX/Neutrino коренным образом пересмотрена стратегия встраивания. В первоначальном варианте QNX4 встраиваемость обеспечивалась только частично. Затем появилась QNX/Neutrino, которая с самого начала разрабатывалась как встраиваемая. В качестве премии, QNX4 подверглась некоторой модернизации на основе опыта, полученного с QNX/Neutrino, и теперь является в гораздо более значительной степени встраиваемой, чем ранее. Как бы там ни было, по части встраиваемости QNX/Neutrino и QNX4 отличаются, как день и ночь. QNX4 не содержит никакой реальной поддержки таких вещей как:

• исходящие вызовы ядра (kernel callouts) (прерывание, таймер);

• настройка стартового кода;

• образная файловая система.

а

вот в QNX/Neutrino все это есть. Подробное описание методик встраивания QNX/Neutrino приведено в книге «Построение встраиваемых систем», входящей в комплект документации.

Поддержка многопоточности

В QNX4 есть функция, называемая tfork, которая позволяет вам организовать «многопоточность», создавая процесс с сегментами кода и данных, отображенными в то же адресное пространство, что и у родительского. Создание процесса и потом приведение его к «потокоподобному» виду дает иллюзию создания потока. И хотя в системе обновлений QSSL содержится библиотека поддержки потоков для QNX4, само ядро потоки непосредственно не поддерживает.

В QNX/Neutrino для организации многопоточности применяется POSIX-модель «рthread». Это означает, что там вы увидите (и уже видели в данной книге) знакомые вызовы функций типа pthread_create, pthread_mutex_lock, и т.п.

Обмен сообщениями

При том что воздействие потоков на обмен сообщениями может показаться минимальным, использование потоков привело к фундаментальному изменению реализации механизма обмена сообщениями (не самой концепции SEND/RECEIVE/REPLY, а именно ее реализации).

В QNX4 сообщения адресовались идентификатору процесса. Чтобы отправить сообщение, нужно было просто найти идентификатор процесса-адресата и выполнить Send. Чтобы сервер мог принять сообщение в QNX4, он должен был вызвать Receive. Это блокировало его до прибытия сообщения. Затем сервер отвечал с помощью функции Reply.

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

Заметьте, что существовавшая в QNX4 функция Creceive, которая выполняла неблокирующий вызов Receive, в QNX/Neutrino отсутствует. Мы вообще не одобряем такие «опрашивающие» функции, особенно когда можно запустить поток; впрочем, если вы настаиваете на выполнении неблокирующего вызова MsgReceive, посмотрите главу «Часы, таймеры и периодические уведомления», раздел «Тайм-ауты ядра». Вот соответствующий пример кода в качестве краткого пояснения:

TimerTimeout(CLOCK_REALTIME, _NTO_TIMEOUT_RECEIVE,

 NULL, NULL, NULL);

rcvid = MsgReceive(...

Импульсы и события

В QNX4 было нечто по имени «прокси». Прокси лучше всего описывается как «законсервированное» (т.е. неизменяемое) сообщение, которое можно отослать владельцу этой (почему-то исторически сложилось, что в русском языке термин «прокси» женского рода; возможно, из-за распространенного сленгового произношения «прокся» #:о) — прим. ред.) прокси от имени процесса или ядра (например, по срабатыванию таймера или из обработчика прерывания). Прокси является неблокирующей для отправителя и принимается точно также, как и любое другое сообщение. Распознать сообщение прокси (то

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

(На самом деле, документация по QNX4 вносит в понятие «прокси» страшную путаницу, которая требует пояснения. Если бы прокси являлась именно сообщением, как это записано в определении прокси, обороты типа «получить сообщение от прокси» были бы лишены смысла. Само по себе слово «proxy» переводится как «промежуточный агент». Если внимательно прочитать главу «IPC via proxies» книги «QNX4 System Architecture», становится ясно, что прокси — это не само сообщение, а специализированный «квазипроцесс», не обладающий ресурсами, но имеющий идентификатор (который, разумеется, по понятным причинам не перекрывается с другими идентификаторами процессов) и способный к обмену специализированными сообщениями. Применяя к прокси с определенным идентификатором функцию Trigger, процесс в QNX4 фактически делает этому квазипроцессу специализированный Send, в ответ на который мгновенно следует Reply, поэтому отправитель (вызвавший Trigger) и не блокируется. Затем прокси отправляет своему процессу-владельцу свое предопределенное сообщение; если владелец прокси в этот момент не является RECEIVE-блокированным, сообщение становится в очередь. Таким образом, правильнее было бы говорить «переключить прокси» вместо «отправить прокси» (о вызове Trigger) и «получить сообщение прокси» вместо «получить прокси» — прим. ред.).

QNX/Neutrino расширяет концепцию прокси введением «импульсов». Импульсы по-прежнему являются неблокирующими сообщениями, и их по-прежнему можно переслать либо от потока к потоку, либо от служебной функции ядра (например, от того же таймера или обработчика прерывания) к потоку. Различие состоит в том, что в то время как прокси имели фиксированное содержимое, импульсы имеют фиксированную длину, но содержимое их может быть изменено отправителем в любой момент. Например, обработчик прерываний (ISR) может сохранить в импульсе какие-либо данные и затем отправить этот импульс потоку.

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

В QNX/Neutrino все это было абстрагировано в расширение POSIX-структуры

struct sigevent
. Все, что использует и возвращает
struct sigevent
, может использовать как сигнал, так и импульс.

На самом деле, функциональность

struct sigevent
была расширена вплоть до возможности создания потока! Мы говорили об этом в Главе «Часы, таймеры и периодические уведомления» в разделе «Уведомление созданием потока».

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

Дракон - не подарок

Суббота Светлана
2. Королевская академия Драко
Фантастика:
фэнтези
6.74
рейтинг книги
Дракон - не подарок

Бастард Императора. Том 8

Орлов Андрей Юрьевич
8. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 8

Чужая дочь

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Чужая дочь

Эра Мангуста. Том 2

Третьяков Андрей
2. Рос: Мангуст
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эра Мангуста. Том 2

Идеальный мир для Лекаря 14

Сапфир Олег
14. Лекарь
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 14

Один на миллион. Трилогия

Земляной Андрей Борисович
Один на миллион
Фантастика:
боевая фантастика
8.95
рейтинг книги
Один на миллион. Трилогия

Помещицы из будущего

Порохня Анна
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Помещицы из будущего

Шлейф сандала

Лерн Анна
Фантастика:
фэнтези
6.00
рейтинг книги
Шлейф сандала

Черный маг императора 2

Герда Александр
2. Черный маг императора
Фантастика:
юмористическая фантастика
попаданцы
аниме
6.00
рейтинг книги
Черный маг императора 2

Император

Рави Ивар
7. Прометей
Фантастика:
фэнтези
7.11
рейтинг книги
Император

Бандит 2

Щепетнов Евгений Владимирович
2. Петр Синельников
Фантастика:
боевая фантастика
5.73
рейтинг книги
Бандит 2

На границе империй. Том 9. Часть 2

INDIGO
15. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 2

Князь Серединного мира

Земляной Андрей Борисович
4. Страж
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Князь Серединного мира

Чайлдфри

Тоцка Тала
Любовные романы:
современные любовные романы
6.51
рейтинг книги
Чайлдфри