Диссертация (1148255), страница 13
Текст из файла (страница 13)
Программная реализацияПринципиальное решение части сформулированных во Введении задачописано в главе 2 (см. Выводы на стр. 71). В данной главе сосредоточимся нанюансах, важных с точки зрения конкретной реализации описанных принципови алгоритмов, продолжив решение оставшихся задач.3.1. Описание реализации прикладного интерфейсаНачинать знакомство с новым решением зачастую оказывается удобнеевсего рассмотрев простейшую программу, в которой это решение используется.
В соответствии с данной традицией приведем пример такой программы нарис. 3.1.1 MDSM_DECLARE(X)2int i ;3 MDSM_DECLARE_END45int main ( )6{7int r e s u l t = 2 ;89MDSM_ACCESS_RW(X)10MDSM_ITEM( i ) = r e s u l t + 1 ;11MDSM_ACCESS_END1213MDSM_ACCESS_RO(X)r e s u l t = MDSM_ITEM( i ) − 3 ;1415MDSM_ACCESS_END161718return r e s u l t ;}Рисунок 3.1 – Пример программы с использованием МАКС DSMПредставленная компактная программа не выполняет какой-либо практи74чески значимой работы, но задействует, тем не менее, почти все возможностиМАКС DSM. Более сложный пример рассмотрен в разделе 3.6, здесь же – рассмотрим основные возможности и интерфейс системы.Строки 1–3 объявляют группу распределённых переменных с именем .В данном примере группа содержит лишь одну переменную целочисленноготипа с именем , но может содержать произвольное количество переменныхили объектов любого типа1 .Строки 9–11 демонстрируют осуществление доступа к переменным группы, причём доступ осуществляется на запись (эксклюзивный доступ).
В терминах принятой модели консистентности (см. раздел 2.2.1) конструкции на строках 9 и 11 определяют и ограничивают соответствующую «критическую секцию».Строки 13–15 аналогичным образом осуществляют доступ на чтение(неэксклюзивный).Все конструкции МАКС DSM, доступные прикладному программисту вкачестве интерфейсных операций, сведём в таблицу 3.12 .Рассмотрим подробности реализации данных интерфейсных операций и,параллельно, найденные способы удовлетворения требований модели интерфейса, описанные в разделе 2.2.5.Синтаксис языка Си++ жестко определён, и, на первый взгляд, если действовать в рамках данного синтаксиса, не удастся создать лаконичное и простоев использовании расширение языка. По сути, в данной ситуации нам необходима техника метапрограммирования3 , позволяющая создать собственный метаязык, превращающийся в язык стандартный при помощи стандартного жекомпилятора.
К счастью, стандарт языка Си++ описывает две функциональ1В текущей реализации отсутствует поддержка ссылок и указателей.2Параметр <имя> в любой конструкции синтаксически должен представлять собой идентификатор языка Си++ с соответствующими ограничениями по именованию.3Метапрограммирование – техника программирования, порождающая метапрограммы (программы, генерирующие другие программы).75НазваниеОписаниеMDSM_DECLARE(<имя>)Начало объявления группы распределённыхпеременных с именем <имя>.MDSM_DECLARE_ENDКонец объявления группы распределённыхпеременных.MDSM_ACCESS_RW(<имя>) Начало критической секции для доступа к распределённым переменным группы<имя>. Доступ на чтение и запись.MDSM_ACCESS_RO(<имя>) Начало критической секции для доступа к распределённым переменным группы<имя>.
Доступ только на чтение.MDSM_ACCESS_ON(<имя>) Начало секции-обработчика события обновления одной или нескольких переменныхгруппы <имя>.MDSM_ACCESS_ENDКонец критической секции.MDSM_ITEM(<имя>)Конструкция доступа к распределённой переменной <имя>.Таблица 3.1 – Операции прикладного интерфейса МАКС DSMные возможности, которые потенциально могут быть использованы для реализации техники метапрограммирования – шаблоны и директивы препроцессора.Шаблоны, однако, подходят нам в меньшей степени – синтаксические конструкции с применением шаблонов оказываются слишком сложны для большинствапрограммистов, а уровень поддержки со стороны компиляторов может различаться от продукта к продукту, что особенно характерно для компиляторов вобласти embedded.
Таким образом, интерфейсная часть МАКС DSM строитсяна директивах стандартного препроцессора не требуя дополнительных инструментов среды разработки.76В соответствии с примером на рис. 3.1, строки 1–3, прикладной программист имеет возможность описывать распределённые переменные такимже образом, как и переменные обычные (локальные), единственное требование – обрамлять группы таких переменных директивами MDSM_DECLARE иMDSM_DECLARE_END. Однако внутри DSM необходимо иметь возможность работы со всеми переменными одной группы как с единым целым, непрерывнойобластью памяти (например, с целью (де)сериализации при передаче по сети).
С этой целью обрамляющие директивы генерируют вокруг переменныхпользователя структуру (struct). Структура, в свою очередь, помещается вкласс (class), предоставляющий необходимые операции управления соответствующей группой распределённых переменных.
С целью предотвращения генерации дубликатов кода, данный класс наследуется от некоторого базовогокласса, реализующего общие для всех подобных классов механизмы. С цельюобеспечения возможности универсальной работы с любым из подобных классов в механизмах, описываемых ниже, все классы генерируются с одним и темже именем. Возможность создания множества групп переменных в одной программе обеспечивается размещением каждого класса в индивидуально сгенерированном пространстве имен (namespace), содержащем в названии уникальныйидентификатор, задаваемый пользователем в качестве параметра конструкцииMDSM_DECLARE.Конструкции MDSM_ACCESS_RW и MDSM_ACCESS_RO, с точки зрения пользователя, открывают критическую секцию для работы с соответствующей группойраспределённых переменных.
С точки зрения реализации, данные конструкции создают переменную-ссылку на экземпляр класса, содержащий интересующие пользователя переменные (параллельно сгенерировав уникальное имясоответствующего пространства имён). В зависимости от типа конструкции(MDSM_ACCESS_RW используется для доступа на чтение и запись, MDSM_ACCESS_RO– только для чтения), ссылка создается либо обычная, либо константная(const). Таким образом предотвращаются возможные ошибки пользователя,77при которых секция открывается на чтение, но в ней производится модификация распределённой переменной.
С целью последующей унификации операцийнад распределёнными переменными, в любой секции ссылка создается всегдас одним и тем же именем. Возможность создания пользователем несколькихкритических секций в пределах одного блока1 обеспечивается генерацией длякаждой критической секции обрамления из фигурных скобок, создающего индивидуальную область видимости для каждой переменной-ссылки.
Сразу послесоздания ссылки на класс, генерируется код для вызова метода этого класса,обеспечивающего консистентность распределённых переменных соответствующей группы.Конструкция MDSM_ACCESS_END завершает критическую секцию. Несмотряна то, что конструкция синтаксически не зависит от типа закрываемой секции(чтение-запись или только чтение), функционально поведение генерируемогокода различается: в случае доступа на чтение, дополнительных вызовов механизмов DSM не производится. В случае же доступа на чтение-запись, вызывается механизм распространения изменений по узлам системы. Синтаксическойидентичности при различном поведении удаётся достичь использованием признака константности ссылки на класс, содержащий распределённые переменные.
В обоих случаях генерируется вызов специального метода данного класса,параметром которому является эта же ссылка. Внутри класса определено двефункции с одним и тем же именем (техника перегрузки), но различающихсяналичием и отсутствием спецификатора const у параметра. Соответственно,константная версия функции содержит пустую реализацию, вторая же – вызовмеханизма распространения данных.Конструкция MDSM_ITEM генерирует лишь обращение к указанной пользователем распределённой переменной, используя известное системе константноеимя ссылки на класс, данную переменную содержащий.1Блок – область программы, ограниченная фигурными скобками. Видимость локальной переменнойограничивается блоком, в котором она определена и распространяется на вложенные блоки.78Конструкция MDSM_ACCESS_ON стоит несколько особняком – поясним её назначение чуть подробнее.
На практике часто возникает необходимость отслеживать изменение распределённых данных. Это нужно, например, при отображении на экране информации зависящей от таких данных, или для выполнениядействий, являющихся реакцией на подобное изменение. Задачу можно решитьпутём регулярного опроса текущего значения данных в секции MDSM_ACCESS_RO,однако постоянные блокировки (даже на чтение) создадут существенную инепроизводительную нагрузку на систему DSM. Если же, с целью сократитьнагрузку, использовать вызовы функций задержки – возрастёт латентность,что также не может считаться удачным решением.
Описываемая конструкциякак раз и призвана решить данную задачу. Вход в определяемую ей секциюпроизойдёт лишь после обновления какой-либо распределённой переменной изгруппы с именем, указанным в качестве параметра. Так как секция не выполняет никаких распределённых блокировок, с целью обеспечения целостностиобщих данных, в момент входа в секцию создаётся константная копия соответствующих данных, и именно она используется при обращении к переменным внутри секции.
Удобно размещать подобные секции в отдельных потокахвнутри бесконечных циклов – ресурсы процессора используются в данном случае эффективно, так как в ожидании обновления переменных соответствующейгруппы задача остается заблокированной.Благодаря описанным выше механизмам в МАКС DSM удалось совместить простой синтаксис, проверку на соблюдение пользователем соглашенийсистемы на этапе компиляции и отсутствие зависимости от каких-либо дополнительных компонентов среды разработки.793.2. СообщенияС целью упрощения дальнейших описаний, сведём основные сообщенияМАКС DSM в единую таблицу 3.21 .НазваниеОписаниеCLN_ASK_SRV_RO_LOCKSRV_ASK_BCK_RO_LOCKBCK_CNF_SRV_RO_LOCKБлокировка на чтение (RO).SRV_CNF_CLN_RO_LOCKCLN_ASK_SRV_RW_LOCKSRV_ASK_BCK_RW_LOCKBCK_CNF_SRV_RW_LOCKБлокировка на запись (RW).SRV_CNF_CLN_RW_LOCKCLN_ASK_SRV_UPDATE<данные>SRV_ASK_BCK_UPDATE<данные> Снятие блокировки c обновлениемBCK_CNF_SRV_UPDATEданных на всех узлах.SRV_CNF_CLN_UPDATE<данные>CLN_ASK_SRV_RELEASE_LOCKSRV_ASK_BCK_RELEASE_LOCKСнятие блокировки без обновленияBCK_CNF_SRV_RELEASE_LOCKданных.SRV_CNF_CLN_RELEASE_LOCKТаблица 3.2 – Внутренние сообщения МАКС DSMДля удобства восприятия, все сообщения маркированы префиксами, обозначающими их источник и получателя.