White Papers

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

Внесение ясности в процесс разработки встраиваемых систем и приложений реального времени с целью повышения продуктивности и качества продуктов

Открытые системы

Синхронный С++ для интерактивных приложенийВерсия для печати

Клод Птипьер

Синхронный С++(sC++) определяет активные объекты, содержащие свои собственные исполняемые потоки и способные общаться друг с другом посредством вызова синхронных методов. Автор статьи рассматривает методы моделирования программы в sC++ и сопоставляет возможности языка sC++ с методами событийно-ориентированного программирования.

Разработанный в Федеральной политехнической школе Лозанны (Швейцария) язык sС++ (http://ltiwww.epfl. ch/sCxx) содержит ядро реального времени, многое заимствует от современных теорий моделирования и анализа [1-3] и использует один и тот же синтаксис как для пассивных, так и для активных объектов. Не понимая связи параллельных процессов с объектно-ориентированным программированием, трудно оценить все преимущества использования sC++. Чтобы прояснить эту связь, обратимся к объектно-ориентированной технологии OMT/Rumbaugh [4]. В соответствии с этим методом разработка приложений должна происходить в три фазы: анализ, проектирование и реализация. Во время фазы анализа разрабатываются три модели: объектная, динамическая и функциональная. Фаза проектирования опирается на эти модели.

Объектная модель определяет компоненты данных, уместные для конкретного приложения, их атрибуты и характерные для них операции. Динамическая модель определяет последовательность операций на основе диаграмм состояний. Функциональная модель использует диаграммы потоков данных для определения входных и выходных данных, источников и приемников данных, расположения мест передачи и приема данных. В сущности, объектная модель описывает данные, в то время как две другие модели описывают аспекты, связанные с параллельными процессами. Аспекты, включаемые в функциональную модель, связаны с передачей сообщений и параллельным выполнением.

Для описания параллельных процессов предлагаются и другие расширения объектно-ориентированных языков. Однако авторы этих решений обычно делают акцент на повышении скорости исполнения в случае применения параллельных процессов, а не на большей пригодности процессов для анализа, как в подходе с моделями.

Синтаксис и семантика sC++

Язык sC++ вводит концепцию активного объекта. Синтаксис определений, реализаций, ссылок, вызовов наследования и удаления активного объекта идентичен синтаксису стандартных — или пассивных — объектов. Активный объект может содержать внутреннюю активность, которая выполняется в параллель с активностью других аналогичных объектов. Эта активность может задержать выполнение методов объекта при их вызове извне, пока объект не будет готов принять их [7].

Рис.1. Три вызывающих объекта обращаются к

одному активному объекту. Первый объект

получает готовность выдать вызов, два других

становятся в очередь, пока обработка вызова не

будет завершена

На рис. 1 изображены три объекта, вызывающие метод send() из другого активного объекта. В этом случае первый объект, находящийся в состоянии готовности, может выдать вызов и выполнить метод. Если в это же время один или оба других объекта обращаются к send(), они становятся в очередь, связанную с методом, пока первый объект не закончит обработку вызова. Выполнение метода, принадлежащего активным объектам, неделимо и не пересекается с исполнением других методов того же самого объекта.

Внутренняя активность активного объекта выносится наружу методом, вызываемым телом, которое исполняется в принадлежащем объекту потоке. Это тело имеет то же имя, что и класс, но с префиксом «@», что во многом аналогично конструктору/деструктору. Если тело выполняется, методы блокируются. Они могут выполняться только в том случае, если тело заканчивает работу или если тело приостанавливает работу по оператору accept, содержащему имя вызываемого метода.

Рис.2. Два оператора вызов объекта и accept

выполняются во время рандеву. Один из них

блокируется, пока оба не будут полностью

обработаны
Например, на рис. 2 объект вызывает метод send(), который определяется в объекте obj1. Если obj1 прибывает в оператор accept send до того, как объект obj2 прибудет в оператор obj1.send(), объект obj1 блокируется, пока объект obj2 не вызовет send(). И наоборот, если объект obj2 прибывает в оператор obj1.send() до того, как объект примет send(), объект obj2 блокируется, пока объект obj2 не примет send(). Таким образом сочетание операторов вызова объекта и accept может идентифицироваться как рандеву, во время которого метод выполняется.

Один оператор accept может принять только один метод. Но часто требуется обеспечить выполнение нескольких методов одновременно, как в следующем примере.

1	State1:
2	select {
3		obj1.send(msg);
4		printf(«sent !
»);
5	| |
6		accept recv;
7		printf(«received !
»);
8	| |
9		waituntil (now()+100);
10		printf(«time-out !
»);
11		goto State2
12	 }

Оператор select включает три случая, каждый из которых отделен двойной вертикальной чертой. Каждый случай начинается с оператора-триггера: либо вызывающего, либо принимающего часть рандеву или тайм-аута (строки 3, 6 и 9).

Когда объект выполняет оператор select, он переходит в состояние ожидания, пока не появится одно из событий, определенных триггером. Первое же событие вызывает выполнение операторов, следующих за оператором-триггером, а затем программа выходит из оператора select. Этот оператор позднее должен быть выполнен повторно, если необходимо обработать и другие случаи.

Рис. 3. Часть автомата конечных

состояний, соответствующая примеру

кода в тексте

Функция now() из строки 9 возвращает значение счетчика, расположенного в ядре и отсчитывающего сотые доли секунд. Определенное оператором waituntil событие наступает, если значение счетчика превысит величину, переданную как параметр waituntil, и если за это время не наступило никаких других событий, определенных в операторе select.

Данный фрагмент программы соответствует автомату конечных состояний (Рис. 3).

Наследование и виртуальные методы

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

Наследование может обеспечить класс с различными интерфейсами, определенными его базовым классом и производными классами (созданными через подтипы). В языке sC++ каждый класс имеет дополнительное свойство активности (активный/пассивный) со следующими правилами наследования:

  • пассивный класс может наследовать другой пассивный класс в одном из режимов: личный, публичный, защищенный;
  • активный класс может наследовать другой активный класс в одном из режимов: личный, публичный, защищенный;
  • пассивный класс не может наследовать активный класс;
  • активный класс может наследовать пассивный класс только как личный.

Действительно, было бы небезопасно позволять пассивному классу наследовать активный класс, поскольку вызывающий объект мог бы получить его в активной форме, если класс использует создание подтипов. С другой стороны, включение активных и пассивных объектов как членов класса — в обеих категориях класса — не создает никаких проблем, поскольку имена членов всегда отражают категорию их принадлежности к классу. В довершение всего, программист может переопределить методы пассивного класса, который был унаследован как личный активным классом в публичном режиме. Действуя подобным образом программист может использовать синтаксис, уже установленный для пассивных объектов, например: BaseClass::method. Это свойство может быть использовано для введения пассивных методов в активные объекты.

Рис. 4. Наследование активного класса, в котором

каждый уровень класса имеет свое собственное

независимое тело

Наследование предохраняет тела активных базовых классов. Например, на рис. 4 показано, что каждый уровень класса имеет свое собственное независимое тело. Когда производный класс вызывает метод своего базового класса, производный класс синхронизируется, как и любой другой объект. Базовый класс должен принять метод, чтобы активизировать его выполнение. Когда внешний объект вызывает метод базового класса, создавая подтип, то для выполнения метода нужно принять только базовый класс, принятие производных классов не требуется.

Рис. 5. Поведение автомата

конечных состояний

на классе ActC1

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

В следующем примере активный класс определяет методы a(), b() и c() со свойством виртуальности. Тело принимает методы в следующем порядке: а() или b() принимаются первыми (строки с 9 по 13), затем с() (строка 14), затем опять а() или b() и так далее. На рис. 5 показано состояние конечного автомата на этом классе ActC1.

1	active class ActC1 {
2 	public:
3		virtual void a() {printf («a
»); }
4		virtual void b() {}
5		virtual void c() {}
6	private:
7		@ActC1() {
8 			for (;;) {
9			  select {
10			      accept a;
11			| |
12			      accept b;
13			}
14			    accept c;
15			}
16		}
17	};

Благодаря ключевому слову virtual этот класс позволяет переопределить как свои действия, так и свои состояния. Например, следующий класс ActC1Deriv переопределяет методы b() и c() (строки 3 и 4), а также добавляет к их телам новые ограничения на то, как эти методы выполняются (строки с 9 по 15). Оба класса должны теперь одновременно принимать объект «b() соответственно с()», чтобы вычислить «b() соответственно с()».

Рис. 6. Для автомата

конечных состояний,

показанного на рис.5,

новое состояние

добавляется между

b() и x()
1	active class ActC1Deriv:public ActC1 {
2 	public:
3 		void b() {}	// redefinition
4 		void c() {}	// redefinition
5 		void x() {}	// new definition
6 	private:
7		@ActC1Deriv () {
8 			for (;;) {
9			     select {
10				accept c;
11			    | |
12				accept b;
13				accept x;
14				accept c;
15				}
16			}
17		}
18	 };

1 2 3

18.03.1999г


Также в разделе:

Новости ОСП-ТВ - 17.03.10


18/03/1999 №03

Долговременное хранение объектов в объектно-ориентированных приложениях
В. Шринивасан
Объектно-ориентированные модели быстро завоевывают популярность у программистов. В большинстве приложений применяются данные, постоянно хранящиеся в памяти, поэтому реальную практическую пользу могут принести только те приложения, которые поддерживают такого рода объекты. Для реализации этой поддержки предлагаются три класса решений.
Векторно-параллельные суперкомпьютеры NEC
Михаил Кузьминский
Еще год-другой назад многие, в том числе автор этой статьи, предсказывали, что векторно-параллельные (PVP, parallel vector processing) суперкомпьютеры будут все больше вытесняться массивно-параллельными системами. Для такого прогноза были весьма серьезные основания.
Проблемы сетевых файловых систем
Виктор Коваленко
Вряд ли кто-нибудь сегодня станет возражать против того, что одним из краеугольных камней любой вычислительной среды является файловая система. Более того, существует глубокая взаимосвязь модели управления файлами с возможностями и формами работы, доступными как пользователям, так и программистам.
Открытые системы сегодня

В ожидании Merced — корпорация Intel? ?и остальной мир Премьера Pentium III Наследие Digital на службе у Compaq Высоты масштабирования Linux HP делится Большое объединение Моцарт и Internet Новая версия HP-UX



Эта рубрика в архиве
Список номеров за



OSP.RU :: Написать письмо.