1[12:12] 2[13:13] 2[13:13] 2[13:13] 2[13:13]
2[13:13] 2[13:13] 2[13:13] 2[13:13] 2[13:13]
2[13:13] 1[12:12] 1[12:12] 1[12:12] 1[12:12]
1[12:12] 1[12:12] 1[12:12] 1[12:12] 1[12:12]
repeating number = 100000, debug level = 1, lock on semaphore
1[12:12] 1[12:12] 1[12:12] 1[12:12] 1[12:12]
1[12:12] 1[12:12] 1[12:12] 1[12:12] 1[12:12]
0[11:11] 0[11:11] 0[11:11] 0[11:11] 0[11:11]
0[11:11] 0[11:11] 0[11:11] 0[11:11] 0[11:11]
2[13:13] 2[13:13] 2[13:13] 2[13:13] 2[13:13]
2[13:13] 2[13:13] 2[13:13] 2[13:13] 2[13:13]
Тестовые потоки запускаются с приоритетами 11, 12, 13, а запускающий поток имеет приоритет 10.
В первом случае нет взаимного блокирования потоков. Все потоки выполняются в такой последовательности 2-1-0 в соответствии со своими статическими приоритетами, указанными перед выполнением. А динамиеский приоритет равен статическому.
Во втором случае — взаимное блокирование на мютексе. Поток 0 начинает выполняться, «почувствовав» блокирование со стороны 2, под приоритетом ожидающего потока 2 ([11:13]), вытесняет поток 1. Затем, освободив мютекс, передает управлению потоку 2, после его завершения потоку 1. это наследование приоритетов, препятствующее возникновению инверсии приоритетов.
В третьем случае - блокирование на семафоре. Здесь потоки выполняются в таком порядке: 1-0-3 — это инверсия приоритетов.
А вот краткий вывод того же самого:
repeating number = 100000, debug level = 1
222222222211111111110000000000
repeating number = 100000, debug level = 1, lock on mutex
000000000012222222222111111111
repeating number = 100000, debug level = 1, lock on semaphore
111111111100000000002222222222
Теперь если запустить немного измененный код этой программы для Windows, то получим следующее:
repeating number = 500000, no priority
210021021021012211020021220101
repeating number = 500000
011111111110002222222222000000
repeating number = 500000, lock on mutex
000000000022222222221111111111
Как ни странно в Windows, не должно быть принято никаких мр по защите от инверсии приоритетов, так как она не ориентирована на realtime поведение, но в третьем случае мы видим отчетливое наследование приоритетов при блокирование на мютексе. А в первом случае наблюдаются перебои ( там потоки равного приоритета) в отличие от QNX.
Драйверы
В случае ОС реального времени для встраиваемого оборудования необходимость написания драйверов — обычное дело. Поэтому разработчики QNX (фирма QSSL) создали беспрецедентную по своей простоте — технологию создания драйверов. Это если сравнивать с техникой драйверов в системах: OS-360 — IBM/360; MS-DOS; Windows 95/98; Linux x86. Почему такую технологию удалось создать в QNX? Ответ — все дело в микроядре. ОС QNX построена на редко реализуемой в ОС концепции — коммутации сообщений. Ядро ОС при этом выступает в качестве компактного коммутатора сообщений между взаимодействующими программными компонентами. Все запросы, обслуживаемые драйвером, предусматриваемые POSIX ( open(), read()...), реально же посылаются драйверу (менеджеру ресурса) в виде сообщений уровня микроядра. Код сообщения определяет тип операции, а последующее тело сообщения — конкретные параметры запроса, зависящие от типа операции. ( в этой технике могут обрабатываться и сообщения произвольных, не специфицированных системой типов, несущих в себе любой пользовательский каприз). Вот порядок взаимодействия:
В этой ОС все запросы API пакуются в тело сообщений, а микроядро системы обеспечивает их синхронизацию и доставку от отправителя к получателю. Для любых взаимодействий в ОС имеется единый механизм передачи, приема и обработки запросов, однако в других семействах ОС такого нет.
Из этого понятно, что:
· любой драйвер (менеджер ресурса) в этой логической модели рассматривается, как сервер некоторой услуги (ресурса), предоставляющий сервис клиентам — пользовательским приложениям;
· драйвер теперь выглядит как и заурядное приложение в системе, а значит может загружаться и выгружаться динамически;
· ОС становится защищенной от ошибок функционирования драйверов, как и от задачи пользовательского уровня — они работают в разных кольцах аппаратной защиты памяти;
· возможность динамически выгружать и загружать драйвера — путь к построению систем высокой живучести;
· драйвер может быть написан на С/С++;
· обеспечивается полная переносимость исходного кода;
· единообразно и автоматически обеспечиваются механизмы синхронизации в ОС на низшем уровне синхронизации сообщений микроядром;
· огромный плюс: драйвер-сервер совершенно одинаково обслуживает запросы клиентов как со своего компьютера, так и с любого другого по сети QNET (сетевая система QNX)
Программирование для GUI
PhAB — Photon Application Builder, который включается в дистрибутивы QNX, по сути не является IDE в привычном смысле: он не содержит редактор исходного кода, символьного отладчика, не генерирует даже проект, в отличие от Borland C++ Builder, MS Visual C++, например. Это скорее строитель GUI-образов приложения: PhAB избавляет разработчика от рутины по отслеживанию размеров, цветов и прочего, и позволяет привязать обрабатывающий код к GUI-событиям. Весь же программный код реакции на события разработчик прописывает традиционными методами на C/C++.
Вот рабочий стол построителя:
Программирование в сетях
Для ОС QNX существует специфичная утилита on, аналога которой нет в других операционных системах. Это своеобразная надстройка над интерпретатором shell. Можно сказать, что это сетевое расширение интерпретатора. Существуют очень много способов удаленного запуска процессов и обмена данными между ними. В QNX создана своя собственная, отличная от IP сеть. Сеть QNX настолько прозрачна, что использование механизмов, подобных тем, что имеются в других ОС, в ней не требуется. Процессы «общаются» друг с другом посредством сообщений микроядра, причем находятся они на одном компьютере, или на разных — не имеет значения.
Эта утилита позволяет:
1. Запускать процессы на удаленном узле QNX сети;
2. Запускать процессы с удаленного узла QNX сети;
3. Запускать процессы с установленным фиксированным уровнем приоритета (1-63);
4. Запускать процессы на другом терминале (перенаправление ввода/вывода и установка управляющего терминала);
5. Запускать процессы от имени другого пользователя (при наличии привилегий администратора);
6. Останавливать процесс сразу после запуска для отладочных целей. Это позволяет присоединить к процессу отладчик и продолжить его выполнение вручную.
В работе было проведено исследование ОСРВ на примере QNX Neutrino, архитектура, диспетчеризация потоков, защита от инверсии приоритетов, т.е. основные требования к ОСРВ. Так же выявлены некоторые особенности написания прикладных программ под QNX.
ОСРВ — специфичная система, к которой предъявляется множество требований. От них зависит правильность и своевременность выполнения задач. Важно, чтобы она отвечала этим требованиям.
Широкое применение получила ОСРВ QNX, причем даже сами разработчики удивлены, что она нашла применение во многих областях науки и техники, в промышленности. А всё вытекает из ее гибкой и элегантной архитектуры. Единственный минус — это его стоимость, но все равно он занимает лидирующую позицию среди ОСРВ на платформе ПК.