Отличие микроядра Neutrino от наноядра QNX - возможность создания "системного процесса", причем в данном случае имеется в виду процесс, взаимодействующий с системой непосредственно, в обход менеджера процессов. В QNX4 ядро и менеджер процессов запускались в едином адресном пространстве, что делало их фактически единым целым. Такой подход снижает надежность, но увеличивает производительность. Во многих конкурирующих ОСРВ такой подход применяется ко всем приложениям, а в QNX4 это - единичный случай. Этот факт, конечно, радует. Но, как всегда, появился побочный эффект (хорошо, что только один, и еще лучше, что от него удалось избавиться, но я забегаю вперед). В случае использования под QNX только одного приложения (не такая уж и редкостная для встроенных систем ситуация) приходилось использовать менеджер процессов, хотя это и бессмысленно - ведь приложение единственное, и делить ресурсы ему не с кем. На основе ядра Neutrino можно создать так называемый "системный процесс" (просто у системных программистов не хватило фантазии на что-нибудь вроде quazi-kernel или OS-Level-App), то есть пользовательское приложение, функционирующее на уровне ОС. Просто до гениальности: сплавляем микроядро Neutrino со своей программой управления Терминатором, и получаем быструю (потому что это голое ядро), компактную (потому что выкинули менеджер процессов), автономную микропрограмму, не зависящую от ОС (потому что она и есть ОС) и даже от BIOS (можно организовать начальную загрузку "своими средствами", через модули IPL).

Кстати, интересный вопрос - является ли такой "системный процесс" однозадачной ОС? И может ли вообще однозадачная ОС работать в реальном времени? Однозначно - нет (на оба вопроса). Во-первых, "системный процесс" может распараллелить все что угодно с помощью нитей (threads), которые QNX, конечно, поддерживает. Во-вторых, однозадачная система может быть мягкой системой реального времени (или системой мягкого реального времени, что одно и то же), но ОС жесткого реального времени обязана быть многозадачной. События могут наступить одновременно, и однозадачная система обязательно "потеряет" одно из них. Время отклика зависит в том числе от задержки выполнения прерывания, а контролировать это, например, в DOS - невозможно (это не единственная причина, но самая наглядная). Более того, не все многозадачные ОС это умеют (Windows 95/98/ME не умеет, да и вообще не является истинно многозадачной). Кстати, Windows NT/2000/XP/CE3, формально являющиеся мягкими ОСРВ, реализуют реальное время, но очень уж [мелко-]мягко :). Сколько времени пройдет между ISR (первичный обработчик прерывания) и DPC (вызов отложенной процедуры) - Гейтс его знает. Видимо, поэтому многие системщики вообще не признают мягкие ОСРВ, ведь если система гарантирует обработку сигнала, но не гарантирует, что обработает его "сейчас" (то есть в течение некоторого заранее определенного кванта времени), то она бесполезна в системах реального времени. Действительно, существуют системы критичные ко времени обработки сигнала, в которых промедление смерти подобно (иногда - в буквальном смысле), но мягкие системы реального времени тоже находят свою рыночную нишу.

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

Любая многозадачная ОС должна содержать средства связи между процессами (IPC = interprocess communication), тогда мы сможем создавать приложения, представляющих собой набор взаимосвязанных процессов, в котором каждый процесс
выполняет одну строго определенную функцию. Это важно не только для ОСРВ, но все же именно в ОСРВ производительность напрямую зависит от реализации IPC.

Ядро QNX реализует передачу всех сообщений между всеми процессами во всей системе. Сообщение - это просто пакет данных длиной до 65536 байт, который передается от одной задачи в другую. Ядро никоим образом не изменяет сообщение, просто копирует данные из адресного пространства одного процесса в адресное пространство другого процесса и приостанавливает первый процесс, пока второй не вернет ответное сообщение. Гениальность такого подхода - в его изяществе, функциональности, эффективности и простоте, а эти качества обычно встречаются только по одиночке :). Многие другие ОСРВ тоже реализуют механизм передачи сообщений, но только QNX делает это на уровне ядра.

Попутно замечу, что QNX поддерживает и другие виды IPC (в том числе сигналы, семафоры, исключения, и т.д.), но именно сообщения являются в QNX основным способом передачи информации, потому и поддерживаются непосредственно ядром. Можно, конечно, организовать передачу данных через совместно используемую память, порты, или даже временные файлы, но все эти способы либо медленны, либо ненадежны, либо не работают вне локальной машины. Именно поэтому процессы используют сообщения, даже если вызывают другие функции, ведь системные библиотеки - это надстройка над ядром, а значит, и над системой передачи сообщений. Например, процесс, передающий данные другому процессу по "трубопроводу" (pipe), косвенно передает их в виде сообщений.

Оперирование сообщениями осуществляется вызовом соответствующих функций языка Си: send() - послать, receive() - принять, reply() - ответить, а также нескольких других, предназначенных для обработки коллизий (в смысле - внештатных ситуаций). Процесс-получатель идентифицируется PID'ом, но существуют способы привязки имени процесса к определенному PID'у. Можно получить сообщение постепенно, кусками требуемого размера, что очень удобно в случае, когда сообщений очень много, и необходимо приостановить прием одного для обработки другого. Это позволяет динамически распределять память под принимаемые данные, что избавляет процесс от излишнего количества буферов.

Вот как происходит передача сообщения от процесса А к процессу В:

1.Процесс А вызывает функцию ядра send(), после чего становится SEND-блокированным.
2.Ядро передает сообщение процессу В.
3.Процесс В выдает receive().
4.Ядро информирует процесс А, что его сообщение процессом В получено. Процесс А изменяет свое состояние на REPLY-блокированное.
5.Процесс В выдает reply().
6. Ядро передает процессу А ответное сообщение процесса В. Процесс А
разблокируется.

Иногда все происходит чуть-чуть сложнее, с использованием receive-блокировки процесса В, тогда после передачи
разблокируются оба процесса, а какой из них начнет работу первым, зависит от их приоритетов. Существуют еще более сложные схемы.

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

Маленький пример. Допустим, происходит передача сообщения по вышеприведенной схеме. После того, как процесс А выдаст запрос send(), он приостанавливается, следовательно, ему нужно меньше ресурсов, чем процессу В, который занят обработкой данных, полученных от процесса А. Поэтому процесс В после выдачи запроса receive() может продолжать свою работу до тех пор, пока не будет готов ответ для процесса А (или пока не поступит сообщение от какого-нибудь другого процесса С).

Выше уже упоминалось, что процесс блокируется до тех пор, пока не получит ответ на сообщение, но это не всегда приемлемо. Например, процессу требуется обслуживать несколько высокоскоростных устройств и одновременно общаться с другими процессами. На этот случай существует функция creceive(), которая в случае отсутствия сообщения немедленно делает return(), а в остальном идентична receive(). Именно этот принцип обеспечивает высокую производительность таких задач, как Dev и Fsys.

Надеюсь, ты понимаешь, что это далеко не все. Я бы хотел рассказать больше (о передаче сообщений через proxy-процесс, например, или о виртуальных каналах), но пытаться втиснуть в статью материал, которого хватило бы на несколько толстых книжек - бессмысленно. Надеюсь, я пробудил у тебя желание изучать QNX самостоятельно. Значит, не зря... Продолжаем дальше.


3. QNX - это сеть.

Любая сеть на основе QNX представляет собой единый набор ресурсов. Любой процесс на любой машине сети может использовать любой ресурс любой другой машины, а также взаимодействовать с любым процессом посредством сообщений. С точки зрения пользователя нет никакой разницы между своим компьютером и чужим: доступ к файлам, использование устройств и запуск приложений осуществляется одинаково (с учетом прав доступа, конечно). Механизм передачи сообщений обеспечивает гибкую и прозрачную сетевую обработку, что не удивительно - QNX изначально разрабатывалась как сетевая операционная система. Сетевые технологии QNX, кстати, получили название Qnet.

QNX-сеть похожа на универсальную вычислительную машину (в простонаречии - мэйнфрейм), только собранную из обычных компов. Например, программы, управляющие работой устройств ввода/вывода, работающие в реальном времени, могут потребовать больше ресурсов, чем другие, менее критичные ко времени, приложения (текстовый редактор, например). Qnet достаточно реактивна для того, чтобы поддерживать оба типа приложений одновременно: вычислительная мощность будет сконцентрирована там, где и когда это необходимо, без ущерба для параллельной обработки данных. Получается что-то вроде кластерного суперкомпьютера, причем "прямо из коробки", а если использовать в качестве транспорта не FLEET (собственный сетевой протокол QNX), а TCP/IP, то можно распараллелить задачу на глобальную сеть...

Каждому узлу сети QNX присвоен номер от 1 до 255, являющийся его идентификатором. Сервер обычно получает номер 1, так что если у тебя номер другой - ты в сети :), причем не в качестве администратора %). В любом случае, ты можешь рассматривать тот компьютер, за которым работаешь (localhost), как номер 0. Другими словами, //0 = 127.0.0.1, если так тебе понятнее.

Сетевой администратор/ менеджер/ диспетчер/
называй-как-хочешь, взаимодействуя непосредственно с ядром, расширяет возможности Кьюникса, обеспечивая передачу сообщений по сети. При этом используются те же самые системные вызовы send(), receive(), reply() и так далее. Такая высокая степень прозрачности обеспечивает эффективную передачу всех транзакций между процессами системы, как по внутренней шине компьютера, так и по сети. Кроме того, менеджер сети пытается увеличивает пропускную способность посредством
балансировки нагрузки и обеспечить отказоустойчивость за счет избыточной связности.

Скорость передачи данных в сети зависит от
бысродействия используемых в ней компьютеров и от пропускной способности сети. Если компьютеры тормозят, менеджер сети тут не поможет :), но если компьютер выдает данные в сеть быстрее, чем сетевое оборудование может обработать их, то в этом случае можно попытаться передавать данные по нескольким сетевым интерфейсам одновременно. Сетевой администратор способен автоматически сбалансировать нагрузку, распределяя трафик по нескольким сетям в реальном времени. Для этого необходимо, чтобы хотя бы в некоторых машинах сети (по крайней мере в двух) стояло несколько сетевых карт. Можно попытаться оптимизировать топологию сети,
объединив компьютеры с высокими требованиями к скорости трафика в одну сеть, а низкоскоростные соединения - в другую. В любом случае, чем больше вариантов путей для передачи данных предполагает топология сети, тем больше у администратора сети (имеется в виду программа, а не человек, хотя и это тоже...) возможностей по оптимизации трафика.

Избыточная топология сети обеспечивает бОльшую надежность. В случае выхода из строя одной из сетевых карт сетевой администратор автоматически перенаправляет весь поток данных по другой сети. Это обеспечивает прозрачную сетевую отказоустойчивость. Можно даже
объединить все компьютеры сети каким-нибудь дешевым интерфейсом (например, последовательным или параллельным соединением), который послужит резервной сетью. В случае полного выхода из строя всей сети (кто-то подал на общую шину 10 тысяч вольт, и все сетевые карты сгорели :)) передача данных не прервется, хотя пропускная способность сети, конечно, снизится.

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

1 комментарий

  1. Аватар

    13.10.2014 в 10:51

Оставить мнение