Содержание к диссертации
Введение
1 Проблемы проектирования высоконадежных программно-информационных систем 11
1.1 Проблемы проектирования надежного программного обеспечения 11
1.2 Проблемы проектирования распределенных информационных систем 16
2 Методы обеспечения отказоустойчивости программного обеспечения 20
2.1 Структура и алгоритмы программного обеспечения 20
2.2 Обнаружение ошибок 22
2.3 Обработка исключений 26
2.4 Контрольные точки и рестарт 27
2.5 Парные процессы 28
2.6 Разнообразие Данных 29
2.7 Проблемы использования контрольных точек 31
2.8 Выводы 34
3 Применение методологии мультиверсий для обеспечения отказоустойчивости программного обеспечения 35
3.1 Блоки восстановления 35
3.2 N-версиошюе программирование 37
3.3 N-версионное программирование с самоконтролем 38
3.4 Блоки восстановления с согласованием 39
3.5 Проблемы мультиверсиошюго программного обеспечения 41
3.5.1 Разработка мультиверсиошюго программного обеспечения 41
3.5.2 Алгоритмы выбора вывода 44
3.6 Отказоустойчивость в операционных системах 48
3.7 Выводы 50
4 Модульные принципы построения программного обеспечения 52
4.1 Требования, предъявляемые к модулям программного обеспечения 52
4.1.1 Динамическое подключение модулей 53
4.1.2 Инкапсуляция 53
4.1.3 Защита модуля 55
4.1.4 Независимость от языка 57
4.2 Объектно-ориентированные методы проектирования модулей программного обеспечения 58
4.3 Проблемы разработки модулей программного обеспечения с использованием объектно-ориентированных методов проектирования 60
4.3.1 Проблемы распространения программного обеспечения 61
4.3.2 Проблемы стандартизации на двоичном уровне 65
4.3.3 Проблемы инкапсуляции 67
4.4 Технологии компонентного проектирования 72
4.4.1 Компонентная объектная модель (Component Object Model, COM). 75
4.4.2 Общая архитектура брокеров объектных запросов (Common Object Request Broker Architecture, CORBA) 83
4.5 Выводы 91
5 Построение мультиверсионного программного обеспечения с использованием технологии компонентного проектирования (СОМ) 93
5.1 MVS комплекс. Детали и составные части 94
5.1.1 Клиентский ЕХЕ-модуль 100
5.1.2 Компонент MvsEnvelope 101
5.1.3 Компонент MvsIO 102
5.1.4 Компоненты MvsProg[l, 2, ., N] 102
5.1.5 Компонент MvsSolver 102
5.1.6 Компонент MvsUserlnterface 103
5.2 MVS комплекс в работе 103
5.3 Результаты тестирования MVS комплекса 104
5.4 Выводы 112
4 Заключение 113
Список использованных источников "..' 115
- Проблемы проектирования распределенных информационных систем
- Проблемы использования контрольных точек
- Разработка мультиверсиошюго программного обеспечения
- Проблемы распространения программного обеспечения
Введение к работе
Программное обеспечение проникает во многие области современной жизни. На научные исследования, производство, транспорт, медицина, быт, и на многие другие секторы, которые влияют на нашу жизнь, воздействуют непосредственно или косвенно программные системы. Гибкость программно-информационных систем, постоянно повышающиеся потребности общества и конкуренция в бизнесе способствуют расширению области применения программных средств. Без программного обеспечения многие из наших современных достижений были бы фактически невозможны.
Несмотря на широкое распространение, программное обеспечение едва когда-либо было "совершенно". Из-за огромного количества причин, чрезвычайно трудно создать безупречное программное обеспечение. Согласно [1], "программное обеспечение - систематическое представление и обработка знаний человека". Для людей совершенное знание проблемы и ее решение редко достигается. В [2] заявлено, что "программы - это не больше, чем наилучшее представление программиста о том, что система должна делать". Даже если программист достаточно квалифицирован для решения проблемы, то знание должно быть преобразовано в систематическое представление, адекватное для автоматической обработки. Современные компьютеры беспощадны, когда работают с программным обеспечением: если есть ошибка в логике, рано или поздно эта ошибка обнаружится на выходе независимо от последствий. Только наиболее тривиальные программные решения могут быть выполнены без ошибок. Поскольку компьютеры применяются для решения все более сложных проблем, то растет вероятность логических ошибок присутствующих в программном обеспечении.
Использование программных систем во многих областях науки и производства, предъявляет высокие требования к надежности программных средств. Такими областями являются различные автоматические системы управления и обработки данных: банковская система, космос, подводные и
подземные исследования, химическое производство, прогнозирование, медицина и другие. Сбой программных систем в подобных областях может повлечь за собой большие потери и иметь весьма серьезные последствия. Поскольку абсолютная уверенность в безупречности программных средств редко достигается, применяются методы повышения отказоустойчивости программного обеспечения для выполнения требований надежности проекта. Программная отказоустойчивость достигается благодаря испол ьзованию алгоритмов программирования и методов разработки программного обеспечения, которые повышают вероятности того, что конечная реализация проекта приведет к правильному и/или безопасному результату. Так как правильность и безопасность - концепции системного уровня, потребность и степень использования программной отказоустойчивости непосредственно зависит от предназначения приложения и полного проектирования систем.
На сегодняшний день разработаны различные методы проектирования отказоустойчивого программного обеспечения. Среди них одним из наиболее перспективных является метод мультиверсионного проектирования. Он состоит в том, что в систему включаются несколько программных компонент, дублирующих друг друга по своему целевому назначению. Мультиверсиошюсть исполнения программных компонент обеспечивает функционирование системы независимо от скрытых ошибок отдельных версий. Ключевое преимущество мультиверсионного программного обеспечения состоит в том, что сбой системы может произойти только в единственном случае - в случае сбоя существенного числа модулей. Вероятность одновременного сбоя обратно пропорциональна числу модулей системы. Модули подтверждают работу друг друга, так что мы можем быть уверенны в точности результатов, которые они выбирают вместе.
Мультиверсионное программирование систем управления предполагает, что возникновение сбоя в функционально эквивалентных модулях происходит в различных точках, благодаря чему сбои могут быть обнаружены и исправлены. Независимость сбоев различных модулей является одной из основ
мультиверсионного программного обеспечения. Разработчики
мультиверсионной методологии считают, что это может быть достигнуто с помощью ввода разнообразия. В частности, разнообразие может быть введено в следующих элементах процесса разработки мультиверсионного программного обеспечения:
образование, опыт и местоположение разработчиков;
алгоритмы и структуры данных;
языки программирования;
методы разработки программного обеспечения;
инструментальные средства программирования и среды (включая компиляторы);
методы тестирования и инструментальные средства.
Все эти методы позволяют разработать мультиверсионные программные модули, которые, возможно, производят сбои в различных точках программного кода, но эта независимость сбоев находится на уровне исходных кодов - это является ключевой проблемой. На стадии выполнения мультиверсионных модулей независимость сбоев теряется из-за того, что остались не учтенными возможные взаимодействия модулей в рамках всей программной системы. Модули работают в едином адресном пространстве памяти, разделяют одни и те же ресурсы операционной системы, и из-за этого возникают дополнительные зависимости между модулями мультиверсионного программного обеспечения. Вследствие этого, сбой одного модуля может привести к сбою других или даже к отказу всей системы в целом, что ставит под сомнение надежность мультиверсионных систем и всей методологии в целом. Для решения этой проблемы необходимо сохранить введенное разнообразие при разработке модулей и перенести его на стадию выполнения.
Целью диссертационной работы является разработка технологии проектирования мультиверсионных систем обработки информации и
управления, позволяющей обеспечить независимость исполнения мультиверсионных модулей.
Поставленная цель достигается путем решения следующих задач:
анализ современных методов отказоустойчивости программного обеспечения, анализ методик и моделей построения мультиверсионного программного обеспечения, как программных средств защиты программных систем;
исследование современных объектно-ориентированных методов проектирования программного обеспечения и выявление их основных недостатков, в том числе, существенных при разработке мультиверсионных модулей;
выработка требований к модулям мультиверсионного программного обеспечения и их реализация;
применение современных методов компонентного программирования для построения программного обеспечения мультиверсионных систем управления и обработки информации.
Методы исследования: Методы прикладного системного анализа; объектно-ориентированного программирования; компонентного проектирования сложных программных систем; мультиверсионного проектирования программного обеспечения отказоустойчивых систем управления и метод изменяющихся вероятностей.
Научная новизна работы:
Разработаны требования к модулям мультиверсионного программного обеспечения, учитывающие анализ причин сбоев программных систем управления и обработки информации.
Предложена методика построения мультиверсионных программных систем, отличающаяся от предыдущих использованием технологии компонентного программирования, которая позволяет исключить взаимное влияние мультиверсионных модулей друг на друга и на среду исполнения.
ft 3. Разработана и программно реализована среда исполнения на базе
компонентной архитектуры для распределенной мультиверсионной системы, которая позволяет подключать к среде исполнения любое количество программных модулей, распределяя вычислительную нагрузку на множество машин.
Значение для теории. Результаты, полученные при выполнении
диссертационной работы, создают теоретическую основу для разработки новых
технологий проектирования мультиверсионного программного обеспечения
сложных систем управления, и на основе внедрения современных методов и
. алгоритмов обеспечивают повышение эффективности процессов обработки
Ф информации и управления.
Практическая ценность. Разработанная в диссертации методика
построения мультиверсиоиных программных систем позволяет исключить
взаимное влияние мультиверсиоиных модулей друг на друга, что обеспечит
независимость сбоев/отказов отдельных модулей программных систем.
Созданные таким образом программные системы обработки информации и
управления обладают высоким уровнем отказоустойчивости и без
дополнительных трудозатрат позволяют обеспечить новые программные
средства защиты отказоустойчивых систем управления и обработки информации.
Достоверность полученных результатов подтверждается тестированием
Ф и оценкой результатов применения разработанной системы в исследовательских
прототипах, а также согласованностью расчетных и экспериментальных данных.
На защиту выносятся:
Комплекс требований к модулям мультиверсионного программного обеспечения отказоустойчивых систем управления и обработки информации.
Методика построения мультиверсионного программного обеспечения отказоустойчивых систем управления и обработки информации.
3. Программная реализация среды исполнения на базе компонентной архитектуры для распределенной мультиверсионной системы. Апробация работы. Основные положения и результаты работы прошли апробацию на 46 и 48-й научно-технических конференциях преподавателей, аспирантов и студентов Красноярского государственного технического университета (2003, 2006), на Пленарном заседании Второй Всероссийской конференции «Молодежь и наука: начало 21-го века», посвященной 50-летию КГТУ (2006), на международной AMSE-конференции «Modeling and Simulation -MS'05» (Rouen, Франция, 2005), на ежегодной заочной конференции РАЕН «Современные телекоммуникационные и информационные технологии» (2006). Докладывались на научно-технических семинарах НИИ Систем управления, волновых процессов и технологий (2003-2006 гг.).
Структура и объем работы. Диссертация состоит из введения, пяти глав, заключения и списка литературы.
Проблемы проектирования распределенных информационных систем
В настоящее время практически все большие программные системы являются распределенными. Распределенной называется такая система, в которой обработка информации сосредоточена не на одной вычислительной машине, а распределена между несколькими компьютерами. При проектировании распределенных систем, которое имеет много общего с проектированием любого другого программного обеспечения, все же следует учитывать ряд специфических особенностей [7],
Поскольку в наши дни распределенные системы получили широкое распространение, разработчики программного обеспечения должны быть знакомы с особенностями их проектирования. До недавнего времени все большие системы в основном являлись централизованными, которые запускались на одной главной вычислительной машине (млшфрейме) с подключенными к ней терминалами. Терминалы практически не занимались обработкой информации - вес вычисления выполнялись на главной машине. Разработчикам таких систем не приходилось задумываться о проблемах распределенных вычислений.
Все современные программные системы можно разделить на три больших класса. 1. Прикладные программные системы, предназначенные для работы только на одном персональном компьютере или рабочей станции. К ним относятся текстовые процессоры, электронные таблицы, графические системы и т.п.
2. Встроенные системы, предназначенные для работы на одном процессоре либо на интегрированной группе процессоров, К ним относятся системы управления бытовыми устройствами, различными приборами и др.
3. Распределенные системы, в которых программное обеспечение выполняется на слабо интегрированной группе параллельно работающих процессоров, связанных через сеть, К ним относятся системы банкоматов, принадлежащих какому-либо банку, издательские системы, системы программного обеспечения коллективного пользования и др.
В настоящее время между перечисленными классами программных систем существуют четкие границы, которые в дальнейшем будут все более стираться. Со временем, когда высокоскоростные беспроводные сети станут широкодоступными, появится возможности динамически интегрировать устройства со встроенными программными системами, например электронные органайзеры с более общими системами. В книге [7] выделено шесть основных характеристик распределенных систем,
1. Совместное использование ресурсов. Распределенные системы допускают совместное использование аппаратных и программных ресурсов, например жестких дисков, принтеров, файлов, компиляторов и т.п., связанных посредством сети. Очевидно, что разделение ресурсов возможно также в многопользовательских системах, однако в этом случае за предоставление ресурсов и их управление должен отвечать центральный компьютер.
2. Открытость, Это возможность расширять систему путем добавления новых ресурсов. Распределенные системы - это открытые системы, к которым подключают аппаратное и программное обеспечение от разных производителей. Параллельность. В распределенных системах несколько процессов могут одновременно выполняться на разных компьютерах в сети. Эти процессы могут (но не обязательно) взаимодействовать друг с другом во время их выполнения.
Масштабируемость. В принципе все распределенные системы являются масштабируемыми: чтобы система соответствовала новым требованиям, ее можно наращивать посредством добавления новых вычислительных ресурсов. Но на практике наращивание может ограничиваться сетью, объединяющей отдельные компьютеры системы. Если подключить много новых машин, пропускная способность сети может оказаться недостаточной.
Отказоустойчивость. Наличие нескольких компьютеров и возможность дублирования информации означает, что распределенные системы устойчивы к определенным аппаратным и программным ошибкам. Большинство распределенных систем в случае ошибки, как правило, могут поддерживать хотя бы частичную функциональность. Полный сбой в работе системы происходит только в случае сетевых ошибок. Прозрачность. Это свойство означает, что пользователям предоставлен полностью прозрачный доступ к ресурсам и в то же время от них скрыта информация о распределении ресурсов в системе. Однако во многих случаях конкретные знания об организации системы помогают пользователю лучше использовать ресурсы. Разумеется, распределенным системам присущ ряд недостатков. Сложность. Распределенные системы сложнее централизованных. Намного труднее понять и оценить свойства распределенных систем в целом, а также тестировать эти системы. Например, здесь производительность системы зависит не от скорости работы одного процессора, а от полосы пропускания сети и скорости работы разных процессоров Перемешая ресурсы из одной части системы в другую, можно радикально повлиять на производительность системы.
2, Безопасность. Обычно доступ к системе можно получить с нескольких разных машин, сообщения в сети могут просматриваться или перехватываться. Поэтому, в распределенной системе намного сложнее поддерживать безопасность,
3, Управляемость. Система может состоять из разнотипных компьютеров, на которых могут быть установлены разные версии операционных систем. Ошибки на одной машине могут распространиться на другие машины с непредсказуемыми последствиями. Поэтому требуется значительно больше усилий, чтобы управлять и поддерживать систему в рабочем состоянии.
4, Непредсказуемость- Как известно всем пользователям Web-сети, реакция распределенных систем па определенные события непредсказуема и зависит от полной загрузки системы, ее организации и сетевой нагрузки. Так как все эти параметры могут постоянно меняться, время, затраченное на выполнение запроса пользователя, в тот или иной момент может существенно различаться.
Проблемы использования контрольных точек
В этом разделе рассматриваются проблемы тлтп-юптия шич рольных точек во время исполнения программы. Методы, упомянутые выше, щюитодт мгновенное обшіружеіше обоев в момеш, когда ошибка агпши;шровллца. Н реальных системах эти задержки обнаружения ненулевые и должны быть приняты но внимание при выборе стратегии хт&пежя контрольных точек. Ненулевые чндіфжіш обнаружений неп уч сводить к нулю ирим щсеша контрольных точеку соли время обнаружений ошибки большее, нем нятерьшл между контрольными шчкши. Как упомянуто выше, существуют два вида использования контрольных точек, которое могут быть использованы в методах с контрольной точкой и рестартом: статические и динамические контрольные точки. Статические контрольные точки используют отдельные снимки состояния в начале исполнения модуля или программы, С этим подходом, система возвращается к началу модуля, когда обнаруживается ошибка, и перезапускает выполнение снова и снова. Этот основной подход к применению контрольных точек обеспечивает универсальную возможность исправления ошибок, которые появляются в течение исполнения. Использование стратегии одной статической контрольной точки позволяет использовать проверки обнаружения ошибок, помещенных на вывод модуля без обязательной необходимости внедрять проверки в код. Проблема в этом подходе состоит в том, что из-за присутствия случайных ошибок, ожидаемое время завершения исполнения растет по экспоненте с объемом обработки. Тем не менее, из-за затрат, связанных с использованием контрольных точек (например: создание контрольных точек, перезагрузка контрольных точек, перезапуск), метод единственный контрольной точки наиболее эффективный когда объем обработки сравнительно небольшой.
Динамическое использование контрольных точек нацелено на сокращение времени исполнения, когда требуется большая обработка в присутствии случайных ошибок, сохраняя информацию о состоянии в промежуточных точках во время исполнения. В общем случае, с использованием динамических контрольных точек, возможно, достигнуть линейного увеличения фактического времени исполнения, согласно росту объема обработки. Из-за накладных расходов связанных с использованием контрольных точек и рестарта, существует оптимальное число контрольных точек для оптимизации некоторых критериев производительности. Факторы, которые влияют на производительность использования контрольных точек, включают требования на исполнение, накладные расходы на отказоустойчивость (то есть, проверки обнаружения ошибок, создание контрольных точек, восстановление, и т.д.), интенсивность появления ошибок, и интервал между контрольными точками. Поскольку контрольные точки созданы динамически во время обработки, проверки обнаружения ошибок должны быть внедрены в код и исполнены прежде, чем контрольные точки будут созданы. Это увеличивает эффективность проверок и вероятность того, что контрольные точки пригодны для использования после обнаружения ошибок.
В [22] представлены три основные стратегии использования динамических контрольных точек: равноудаленная, модульная, и случайная. При использовании равноудаленных контрольных точек применяется детерминировано установленное время между контрольными точками. В [22] показывается, что для произвольной продолжительности между равноудаленными контрольными точками, ожидаемое временя исполнения, увеличивается линейно с ростом требований на обработку. Оптимальное время между контрольными точками, которое минимизирует полное время исполнения, показывает непосредственную зависимость от интенсивности ошибок и не зависит от требований на обработку.
При модульном использовании контрольных точек их размещают в конце субмодульных компонентов профаммного обеспечения прямо после того, как закончено обнаружение ошибок для каждого субмодуля. Принимая компонент с установленным числом субмодулей, ожидаемое время исполнения непосредственно связано с распределением обработки между субмодулями (то есть, время обработки между контрольными точками). Для заданной интенсивности ошибок, линейная зависимость между временем исполнения и требованием на обработку достигается тогда, когда распределение обработки между модулями равномерно. Для большинства общих случаев, (переменные требования обработки и экспоненциальное распределение в длительное і и субмодулей) время исполнения становится линейной функцией требований на обработку, когда частота контрольных точек больше чем интенсивность ошибок. При случайном использовании контрольных точек процесс создания контрольной точки задается наугад без рассмотрения состояния исполнения программного обеспечения, В данном случае, оптимальная средняя частота применения контрольных точек непосредственно зависит от интенсивности ошибок и не зависит от требований на обработку. С этой оптимальной скоростью введения контрольных точек, время выполнения линейно зависит от требований на обработку.
Разработка мультиверсиошюго программного обеспечения
Существует две критических -F муЛьтиверсионнь,х методов отказоустоинивости проемного о ,„-ЭТо гарантия независимости отказа множественны версни и разраоот,, алгоритмов выбора вывода. разработки программного обеспечения, неопределенность проявляв, в Хтстнии ошибок проектирования „, как следствие, сбое» из-за зти онп Цель методологии разнообразия применительно к разработке программного «ния состоит в том, чтобы формировать версии про.амм, которы выда,от сбои независимо и с низкой вероятного совпадакици сбоев. Не и з ц1 будет достигнута, то уменьшится вероятность неопределенное,,, при ііГоре кордного вывода в конкретно,, тонке во время исполнения „он„ого „много обеспечения, .пользование разнообразия разработки для достижения — программных средств на сегодня, по большому сиету, искусство, а не НеГторые исследователи разработали рекомендации и методик,, „ « дГГи уть желательного уровня разнообразия, „о реализация разнообразия .аммном проекте остается довольно сложным (и спорным, предм т . Оце! достигнутого усовершенствования по отношение к про т пр1Раммного обесценения е одной версией трудна (если вообьце возможна, основана, главным образом, на качественны, параметра, програм..
Возможно, наиболее всесторонние исследования для разраоотк __ проектирования мультнверсионного использование концепций разнообразия проектирования для других аспектов программных систем, например операционных, для аппаратных средств, и интерфейсов пользователя. В [24] представлена методология проектирования для мультиверсионного программного обеспечения, которая рассматривает полный цикл разработки от стадии системных требований до стадии эксплуатации. Цели парадигмы проектирования состоят в том, чтобы уменьшить вероятность конструкторских недоработок, устранять любые источники подобных ошибок проектирования и минимизировать вероятность подобных ошибок вывода. Представленная методология, в основном, соответствует тем же принципам разработки программного обеспечения, которые представлены в главе 2, и это усиливается действиями поддержки разнообразия проектирования. Вопросы, которые должны быть решены, включают:
выбор числа версий программного обеспечения;
оценка требуемого разнообразия (то есть, разнообразия спецификаций, проектирования, кода, и/или тестирований);
оценка использования случайного (или неуправляемого) разнообразия против принудительного (или управляемого) разнообразия, для минимизации общих причин ошибок;
правила изоляции между группами разработки, для уменьшения вероятности подобных конструкторских недоработок;
учреждение группы координирования, которая будет служить посредником между группами разработчиками;
определение строгого протокола связи между группами проектирования и группой координирования, для предотвращения потока информации, которая может приводить к общим конструкторским недоработкам. Подход для обеспечения отказоустойчивости программного обеспечения состоит в том, чтобы осуществить отказоустойчивость на основном системном уровне, допуская разработку прикладных программ с минимумом дейепши для обеспечения отказоустойчивости. Это позволяет прикладным разработчикам сосредотачиваться на их прикладных задачах, без необходимости заботиться об аспектах отказоустойчивости системы. Чтобы осуществлять этот подход, должен быть разработан каркас, который расширяет возможности базовой операционной системы сервисами отказоустойчивости подобно межверсионному взаимодействию, восстановлению при ошибках, и алгоритмам выбора значения вывода ([24, 34]). Как упомянуто выше, сложно определить выгоды от использования разнообразия проектирования для обеспечения отказоустойчивости программного обеспечения. Есть некоторые спсцифицеские проблемы, связанные с этим подходом, включая устранение зависимых отказов и стоимость разработки. Предполагая, что разработка проводится тщательным образом, и разнообразие проектирования применяется к мродукіу на должном уровне, все равно еше остается общий источник ошибок при идентичных входных условиях. В [35] указывается на эксперименты (например [36, 37, 38]) которые показали, что вероятность проявлений ошибки не равномерно распределена по входному пространству, и вероятность совпадающих ошибок зависит от выбранного ввода. Конечно, могут быть использованы методы разнообразия данных для уменьшения воздействия этого источника ошибок, но проблема определения эффективности подхода все равно остается.
Стоимость использования мультиверсионного программного обеспечения - также важный вопрос. Прямое дублирование полных затрат на разработку, включая испытание, является конечно достаточно затратным вариантом. Так как необходима ещё и поддержка среды исполнения, чтобы заверши і ь реали_ицшо, общая стоимость может стать препятствующим барьером для некоторых приложений. Однако уменьшение стоимости может быть произведено за счет разумного использования приемлемых альтернатив. Например, в некоторых приложениях, где только небольшая часть функциональных возможностей критична, разработка и стоимость продукта может быть уменьшена за счет применения разнообразия проектирования только к этим критическим частям [26]. Следует учитывать, что стоимость надежных альтернативных методов проектирования довольно высока из-за потребности в специализированном штате сотрудников и инструментальных средствах, использование же разнообразия проектирования может фактически привести к уменьшению стоимости.
Проблемы распространения программного обеспечения
Библиотеки C++ традиционно распространялись в форме исходною кода. Ожидалось, что пользователи библиотеки будут добавлять реализации исходных файлов и создаваемую ими систему и перекомпилировать библиотечные исходные файлы т месте, с wnmibwmmcu своего компилятора О . Ылп предположить, то библиотека написана на наиболее употребительной версии языка С и% то чйкой подход бып бы вполне работоспособные. Подво/шым камнем этой схемы было jo, что исполняемый код этой библиотеки должен был включаться во все шттпект приложении,
Предположим, что для погашенного ішше класса PastSirhtg сгенерированный мшттиый код &т четырех методов гжш 16 Мбайт пространства в результирующем жиотжмт фшле. Нжюмтт. то при выполнении 0(1)-пояска может потребоваться много пространства для Ш Ш чтобы обесценить заданное время исполнения, дилемма, которая ограничивает большинство алгоритмов. Как показало на рисунке 4.1, если три приложения используют библиотеку fasfSiiing, то каждая т трех испа.пияемык программ будет вкточтъ ш себя по 16 Мбайт кеда. Это отеачжт, то если конечный пользователь инсталлирует все три клиентских приложения, го реализация FastString адймет 48 Мбайт дискового пространства. Хуже того - еслм конечный пользователь шіусгт шх три клиентских прииожения одновременно, то код FastSlring займет 48 Мбайт виртуальной, так кіт операционная система ме может обнаружить дублирующий код, имеющийся в каждой исполняемой
Есть еще одна проблема в таком сценарии; когда разработчик библиотеки находит дефект в классе FastString, нет способа всюду заменить его реализацию. После того как код FastString скомпонован с клиентским приложением, невозможно исправить машинный код FastString непосредственно в компьютере конечного пользователя. Вместо этого разработчик библиотеки должен известить разработчиков каждого клиентского приложения об изменениях в исходном коде и надеяться, что они переделают свои приложения, чтобы получить эффект от этих исправлений, Ясно, что модульность компонента FastString утрачивается, как только клиент запускает компоновщик и заново формирует исполняемый файл.
Один из путей решения этих проблем - упаковка класса FastString в динамически подключаемую библиотеку (Dynamic Link Library - DLL). Это может быть сделано несколькими способами. Простейший из них использовать директиву компилятора, действующую на уровне классов, чтобы засішлпь все методы FastString экспортироваться из DLL, Компилятор Microsoft C++ предусматривает для этого ключевое слово _declspec(dllexport):
В этом случае все методы FastString будут добавлены в список экспорта соответствующей библиотеки DLL, что позволит записать время выполнения каждого метода в его адрес в памяти. Кроме того, компоновщик создаст библиотеку импорта (import library), которая объявляет символы для методов FastString. Вместо того чтобы содержать сам код, библиотека импорта включает в себя ссылки на имя файла DLL и имена экспортируемых символов. Когда клиент обращается к библиотеке импорта, эти ссылки добавляются к исполняемой программе. Это побуждает загрузчик динамически загружать DLL FastString во время выполнения и размещать импортируемые символы в соответствующие ячейки памяти. Это размещение автоматически происходит в момент запуска клиентской программы операционной системой.
Рисунок 4-2 иллюстрирует модель FastString на этапе выполнения (runtime model), объявляемую из DLL. Заметим, что библиотека импорта достаточно мала (примерно вдвое больше, чем суммарный размер экспортируемого символьного текста). Когда класс экспортируется из DLL, код FastString должен присутствовать на жестком диске пользователя только один раз. Если даже несколько клиентов применяют этот код для своей библиотеки, загрузчик операционной системы обладает достаточным интеллектом, чтобы разделить физические страницы памяти, содержащие исполняемый код FastString (только для чтения), между всеми клиентскими программами. Кроме того, если разработчик библиотеки найдет дефект в исходном коде, теоретически возможно послать новую DLL конечному пользователю, исправляя дефектную реализацию для всех клиентских приложений сразу. Ясно, что перемещение библиотеки FastString в DLL является важным шагом на пути превращения класса Сн и заменяемый и эффективный модуль.