Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

СПКД123 / СПДК / Задачи АСУТП / Лекция 13. Программирование задач информационных обменов

.doc
Скачиваний:
87
Добавлен:
04.03.2016
Размер:
340.99 Кб
Скачать

Лекция 13. Программирование задач информационных обменов

Содержание лекции:

  • Роли программ информационного обмена

  • Управление в программах информационных обменов

  • Применение универсальных шаблонов проектирования

  • Конфигурирование программ информационного обмена

  1. Роли программ информационного обмена

На предыдущей лекции нами были рассмотрены информационные обмены ДП АСУТП: взаимодействие с системой телемеханики, передача данных другим информационным системам управления и автоматизации производственно-хозяйственной деятельности.  В системах реального времени программа, выполняющая передачу информации, может играть одну из следующих ролей (реализуя соответствующие функции):

  • Импортер/экспортер – выполняет периодический импорт данных в БД из текстового файла или экспорт данных из БД в текстовый файл.

  • Сервер – выполняет обработку внешних запросов на получение данных.

  • Клиент – по запросам других подсистем ДП АСУТП выполняет обращение к внешнему серверу для получение данных.

Клиент и сервер могут взаимодействовать по-разному: или обмениваясь пакетами байт определенного формата по последовательному каналу или сети передачи данных; или напрямую, используя механизмы распределенной работы приложений (DCOM и, в частности, надстройку над ним – OPC; механизм RPC; системы на базе CORBA и т.д.). Общим для программ всех типов является то, что они не имеют пользовательского интерфейса: выполняясь в многозадачной ОС, они запускаются автоматически при старте программного комплекса ДП или планировщиком процессов по определенному регламенту. Конфигурационные параметры определяются в командной строке, инициализационном файле или считываются непосредственно из определенного объекта базы данных; эти методы могут комбинироваться. Аналогично всем прочим процессам ДП АСУТП, программы информационных обменов ориентированы на непрерывную работу в режиме периодического (или, реже, апериодического) выполнение заложенных алгоритмов. За последние годы производительность ЭВМ – серверов ДП АСУТП выросла намного больше, чем объем передаваемой оперативной технологической информации в единицу времени, поэтому требования к оптимизации программного кода по производительности или объему занимаемой памяти не являются в настоящий момент критическими. Однако от разработчика требуется гарантировать отсутствие «утечек памяти» – динамического выделения памяти без последующего ее освобождения. Помимо их отсутствия в устойчивом режиме работы, требуется обеспечить освобождение выделенной памяти при сбоях (напр., ошибках приема/передачи данных, возникающих на низкокачественных линиях связи тональной частоты), что сильно усложняет процесс тестирования ПО. В этой лекции мы рассмотрим вопросы проектирования структуры программ, реализующих информационные обмены. Здесь, как и в остальных областях, проявляются достоинства объектно-ориентированной методологии, также применимы универсальные шаблоны проектирования, широко рассмотренные в литературе.

  1. ^ Управление в программах информационного обмена

Действия программы, реализующей некоторую передачу информации, всегда управляются внешними событиями. При получении события программа выполняет определенные действия, после чего переходит в режим ожидания. События бывают следующих видов:

  1. Периодические события, получаемые от таймера. 

  2. Периодические или апериодические события, вызванные пользователем. 

  3. Периодические или апериодические события, вызванные поступлением данных.

В первом случае возможно две ситуации: настройка частоты вызовов произведена внешней программой-менеджером, которая, возможно, сама и запустила нашу программу; или сама программа информационного стыка при запуске создала и запустила свой таймер. Для программы-сервера «пользователем» обычно является одна или несколько программ-клиентов, которые выполняют инициализацию, периодически запрашивают наборы данных или сведения об изменении. Для клиента «пользователь» – или программа-менеджер, планировщик процессов и т.п., или оператор ДП АСУТП – графический интерфейс ДП позволяет вводить команды и, посредством процессов ядра ДП АСУТП, передавать их программе-клиенту информационного обмена, не имеющей своего графического интерфейса. События, вызванные поступлением данных, управляют действиями сервера, клиента в случае передачи сервером спонтанных (SRBX) сообщений, программой-импортером (событие – появление нового файла данных).

  1. ^ Применение универсальных шаблонов проектирования

Шаблоны помогают распределить «обязанности» между классами при проектировании системы. Так, К. Ларман в своей книге «Применение UML и шаблонов проектирования» вводит набор общих шаблонов распределения обязанностей (General Responsibility Assignment Software Patterns):

  • Information Expert (информационный эксперт – назначать обязанность следует классу, содержащему данные для ее выполнения); 

  • Low Cohesion (низкая степень связанности – классы должны быть слабо взаимозависимы); 

  • High Coupling (сильное зацепление – класс должен реализовывать связанные обязанности);

  • Creator (обязанность создания объектов следует назначать тому классу, который агрегирует или активно использует их, а также для которых он обладает данными инициализации); 

  • Controller (следует выделять отдельный класс и делегировать ему обязанности по обработке системных и пользовательских событий). 

Классическими книгами по шаблонам проектирования являются: Gamma E., Helm R., Johnson R. And Vlissides J. «Design Patterns»; Buschmann F., Meunier R., Rohnert H., Sommerlad P. «Pattern-Oriented Software Architecture»; Fowler M. «Analysis Patterns: Reusable Object Models» и «Patterns of Enterprise Application Architecture» (см. также www.martinfowler.com). В этих книгах вводятся шаблоны, также распределяющие обязанности, но при этом впрямую влияющие не только на архитектуру, но и на программную реализацию проектируемой системы. Они могут быть разбиты на несколько групп: шаблоны для реализации прецедентов, шаблоны для проектирования взаимодействия с базой данных, шаблоны для распределенной работы, выполнения вычислений и др. Далее мы рассмотрим применение шаблонов при введении и проектировании отдельных модулей программ информационных обменов. При реализации программы-клиента, управляемой обычно событиями первых двух видов, эффективно использование шаблона Controller (иначе – Facade, иногда различают UseCaseController – класс-контроллер, реализующий логику прецедентов, см. рис. 13.1а, и FacadeController – класс, обеспечивающий внешний интерфейс системы, см. рис. 13.1б).  Рис. 13.1. Использование шаблона Controller (Facade). Для некоторых программ требуется реализовать вариативный доступ к различным программным модулям, взаимодействующим с различными ресурсами. Например, передача данных между клиентом и сервером может осуществляться по последовательному каналу связи или по сети, с использованием одного из множества протоколов. В таких случаях применяют шаблон Adapter, который подразумевает введение дополнительного класса, унифицирующего интерфейсы компонентов и принимающего внешние вызовы (выполняет в какой-то мере роль контроллера).  Рис. 13.2. Введение класса-адаптера, унифицирующего интерфейсы. Как адаптер мы модем рассматривать и чистый интерфейс, реализуемый несколькими классами. Тогда, в дополнение используется шаблон Factory (вводится производящий класс (factory class), возвращающий интерфейс и создающий, при необходимости, экземпляр функционального класса). Рис. 13.3. Использование интерфейса-адаптера  и производящего класса. Ряд действий в программах выполняются модулями, существующими в единственном экземпляре в памяти: разбиение массива прикладных данных на фреймы, передаваемые по линии связи, и обратное преобразование; вычисление контрольной суммы; запись сообщений в log-файл. На программном уровне это достигается использованием статического класса/функции, или создания экземпляра и доступ к нему через метод getInstance(). На уровне проектирования «единственный экземпляр объекта в памяти» определяется как шаблон Singleton. Как упоминалось выше, в большинстве протоколов взаимодействие клиента и сервера осуществляется посредством обмена сообщениями. Каждый протокол определяет набор типов сообщений и их структуру: заголовок, область данных и т.п. С точки зрения проектирования, каждый тип сообщения можно представить в виде класса, отношение наследования. Поскольку набор методов, которые требуется реализовать в каждом классе, неизменен (например, конструктор и метод записи атрибутов класса в поток байт, традиционно называемый Serialize()), то получаемая иерархия классов – гомоморфная. Преимущества этого – возможность всегда оперировать указателем на абстрактный базовый класс в уверенности, что никакой производный класс не содержит дополнительных операций и не придется выполнять динамическое приведение или определение типа, и т.о. добиться универсализации работы с сообщениями любых типов в программе. Также при создании иерархии классов сообщений полезно применить метод создания их экземпляров с использованием статической производящей функции (factory function, см. Дж. Элджер «С++: библиотека программиста»). Это также применение шаблона проектирования Factory, позволяющее сокрыть и от клиента, и от сервера все производные от базовых классы сообщений. Производящая функция сама определяет, сообщение какого типа следует создать (опираясь на переданные параметры) и возвращает указатель на базовый класс сообщения. Ориентация клиента и сервера на использование сообщений определенного набора типов, каждый из которых определяет некоторое действие, которое требуется выполнить, также позволяет использовать шаблоны Command и CommandProcessor. Каждое сообщение является командой, а объекты-контроллеры клиента и сервера являются процессорами этих команд, самостоятельно реализующие логику работы с БД на основе этих команд (см. рис. 13.4а). Противоположностью разделения команд и их обработчика была бы инкапсуляция механизма работы с базой данных в классы сообщений. Тогда помимо общего метода Serialize(), в каждом запросе требовалось бы реализовать некоторый метод Run(). Однако такой подход обладает рядом недостатков (см. рис. 13.4б). Во-первых, становится невозможной взаимно независимая, использующая только общий набор классов сообщений, разработка, компиляция и связывание клиента и сервера. Во-вторых, если выполнение самим запросом действий на сервере достаточно легко реализуемо, то «самоформирование» запроса на клиенте весьма затруднительно. В-третьих, создание ответа запросом, а не контроллером сервера приводит к необходимости установления отношения зависимости классов запросов от классов ответов.  Рис. 13.4. Два варианта отношений между классами  клиент-серверного приложения.

  1. Конфигурирование программ информационного обмена

В простейшем случае, программе информационного обмена требуется минимум конфигурационных данных. Это – настройки коммуникации: имя удаленного хоста и номер порта для сетевого клиента; скорость передачи данных, количество стартовых, стоповых и бит данных, четность для сервера и клиента, взаимодействующих по последовательному каналу связи; имена каталога и файлов для программы, выполняющей экспорт/импорт файлов данных.  Однако при этом требуется, чтобы внешний процесс, управляющий программой-клиентом, каждый раз при запросе выполнения определенных действий (чтения, записи) передавал бы и список имен параметров (сигналов), для которых требуется выполнить это действие. В свою очередь, клиент должен передать этот список имен серверу, также получающему информацию «по необходимости». Такой подход неэффективен с точки зрения производительности, т.к. требует передачи существенно больших объемов данных при каждой транзакции, выполнения сервером доступа к данным, используя символьную, а не цифровую адресацию. Недостатком этого подхода также является то, что из-за отсутствия фазы начальной инициализации невозможно определить ошибки в параметрах (именах сигналов в удаленной базе) до того, как будет выполнена попытка чтения или записи каждого из сигналов. Поэтому каждая программа информационного обмена содержит в себе массив конфигурационных данных реализуемого взаимодействия.  Для клиента это таблично организованный список сигналов, который хранится в базе данных или текстовом файле. Каждая строка списка имеет следующие поля (пример):

  • Control – разрешены или нет операции ввода/вывода для данной строки

  • Status – статус успешности/ошибки последней операции со строкой

  • Poll Mask – период выполнения периодического опроса

  • PRBX Mask – период передачи запроса изменений

  • Type (Row Size) – тип данного (или размер строки для таблицы)

  • Row Num – число строк (для векторов, таблиц)

  • Deadband – значение зоны нечувствительности

  • Deadband Type – тип зоны нечувствительности (абсолютная, относительная)

  • Remote Address – адрес сигнала в удаленной базе (пространстве имен сервера)

  • Remote ID – идентификатор сигнала, возвращаемый сервером

  • Local Address – адрес объекта-приемника значения сигнала в локальной базе

  • Error Code – расширенный код ошибки

  • Comment – комментарий

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

  • Инициализация адресного пространства сервера производится клиентом. При установлении соединения, программа-клиент отправляет серверу список имен параметров (см. выше), значения которых будут запрошены в дальнейшем. Сервер проверяет корректность имени каждого параметра, возвращает уникальный идентификатор при успешности или код ошибки. 

  • Сервер формирует свое пространство имен автоматически, опираясь на структуру базы данных, к которой он предоставляет доступ. 

  • Сервер формирует свое пространство имен, используя конфигурационный файл, описывающий структуру установленного измерительного и управляющего оборудования, адреса, типы и прочие характеристики устройств – источников данных (контроллеров, интеллектуального полевого оборудования).

Сохранение конфигурационной информации требует определения структур данных для хранения информации, поиска (доступа) по передающимся в составе сообщений идентификаторам для выполнения требуемых операций. Такие структуры обычно иерархически организованы. На рис. 13.5. приведен пример типовой структуры данных сервера. Для каждого подключившегося клиента сервер создает пространство имен (массив TagsStorage). В него входит шесть групп (коллекций) тегов: 3 группы для скалярных, векторных, табличных сигналов и еще 3 группы – для сигналов, поддерживающих передачу изменений (PRBX-сигналов). Клиент в направляемых серверу запросах (переинициализации – удалении всех тегов из списка, на добавление сигнала, чтение/запись его значений) указывает функциональный код fc, который определяет, с какой группой требуется выполнить операции.  Рис. 13.5. Организация области хранения данных сервера.

1   ...   6   7   8   9   10   11   12   13   14

хорошо

   1