Процессы
Параллельные процессы — классический способ описания поведения сложных систем: независимое управление в каждой подсистеме, локализация данных, развитые средства взаимодействия позволяют описывать системы наиболее понятным для разработчиков способом. Тем не менее, в реальных системах этот способ используется редко из-за низкой эффективности реализации. Дело в том, что в них параллельно существуют тысячи процессов, абсолютное большинство которых находится в неактивном ("подвешенном") состоянии, ожидая каких-либо событий. Традиционным механизмом реализации параллелизма такого типа является диспетчеризация через короткие промежутки времени по сигналам от таймера (системы разделения времени), однако при этом самой частой операцией становится свертка/развертка процессов, сильно увеличивающая накладные расходы системы [27].
Чтобы сделать параллельные процессы эффективными, мы воспользовались особенностью встроенных систем, состоящей в том, что обычно их процессы имеют очень короткие действия — переходы в терминах расширенной конечно-автоматной модели рекомендаций Z.100 МККТТ [29]. Мы считаем, что если процесс получил управление по какому-то входному сигналу, то он должен довести переход до конца (до следующего состояния) и только затем передать управление диспетчеру, который определит, какой из процессов, готовых к исполнению (т.е. получивших сообщения), будет работать следующим. Синхронная организация параллелизма делает возможной простую процедурную реализацию, в отличие от традиционного асинхронного подхода, при реализации которого необходимы процессы. Против синхронной реализации обычно выдвигают два аргумента.
Во-первых, часть сообщений приходит по сети от других ЭВМ или оборудования в непредсказуемое время. Для решения этой проблемы соберем все функциональные процессы в один большой процесс ОС, внутри которого будем использовать синхронную организацию взаимодействия функциональных процессов, а драйверы сети, которые осуществляют буферизацию сообщений (никакой обработки!), будем реализовывать простыми обработчиками прерываний на стеке текущего процесса. Интересно, что на одно внешнее событие обычно приходится 5-10 внутренних переключений функциональных процессов.
Во-вторых, что будет, если один из процессов все-таки имеет слишком длинный переход? Тогда можно вставить несколько промежуточных фиктивных состояний (на практике это встречается крайне редко).
Такая последовательная и непрерываемая организация переходов позволяет процессам пользоваться глобальными данными (кроме списков входных сообщений, к которым имеют доступ параллельно работающие драйверы сети) без семафоров, критических интервалов и других дорогостоящих средств монополизации ресурсов.