И.А. Волкова, И.Г. Головин, Л.Е. Карпов - Системы программирования (1114897), страница 17
Текст из файла (страница 17)
Все статические библиотеки подключаются кпрограммам, готовящимся к выполнению, ровно один раз в момент формированияредактором связей полной программы. После подключения компоненты статическойбиблиотеки становятся неотъемлемой частью программы и в дальнейшемраспространяются вместе с нею. Программа, к которой уже подключены компонентыстатической библиотеки, приобретает независимость от самой этой библиотеки. Если вбиблиотеку будут внесены изменения, вносить какие-либо параллельные изменения впрограмму, использующую исправленную библиотеку не требуется.
Связь программыи библиотеки после подключения этой библиотеки к программе разрывается. Этосвойство статических библиотек является их несомненным преимуществом.Другой стороной разрыва связи программы и библиотеки в момент ихобъединения является трудоемкость исправления программ в случае, если внесениеизменений в библиотеку объясняется исправлением существовавшей в ней ошибки. Этатрудоемкость связана с необходимостью произвести повторную полную сборкупрограммы из объектных модулей и исправленных библиотечных компонентов.Статическое подключение компонентов библиотек к объектным модулям ведетк существенному росту объемов готовых программ.
В современных условиях, когдабиблиотеки достигли высокой степени развития, доля компонентов библиотек в объемеготовых программ уже превышает половину этого объема. Поскольку некоторымисистемными и стандартными библиотеками пользуются почти все программы, размеры63непроизводительно используемой памяти, как в архивах программ, так и в памятивычислительных машин при выполнении программ, могут быть очень большими.3.6.2. Динамически загружаемые библиотекиКомпоненты динамических библиотек (динамически загружаемые компоненты ибиблиотеки) подключаются к программам во время выполнения этих программ. В этомсостоит основное отличие динамических библиотек от статических.
Компонентыдинамических библиотек не связаны с программами, которые к ним обращаются, ираспространяются отдельно от них.Некоторые динамические библиотеки подключаются к программам в самомначале выполнения программы при ее записи в оперативную память вычислительноймашины. Какой-либо связи с тем, будет в программе реальное обращение ккомпонентам библиотеки или нет, здесь не возникает.
Другие библиотеки попадают воперативную память только тогда, когда происходит реальное обращение к какомунибудь одному из их компонентов (к какой-либо процедуре или функции из этихбиблиотек). Освобождение памяти для разных библиотек также происходит поразному. Память может освобождаться либо после завершения выполнения всейпрограммы, либо по указанию главной программы, которая просигнализирует, чтонекоторая библиотека больше использоваться ею не будет. Возможен и вариант, когдапамять, занимаемая динамически подгруженным компонентом, будет освобожденанепосредственно после завершения выполнения этого компонента.Загрузка при обращении к компоненту библиотеки имеет определенныепреимущества перед загрузкой при начале выполнения программы.
Памятьвычислительной машины при таком методе загрузке библиотек используется болеерационально, но этот метод сложнее для реализации. Он требует либо существенногоусложнения операционной системы, либо внесения в программы специальных указанийдля динамической загрузки, поскольку только разработчик программы может точнознать, когда потребуется загрузка в память той или иной библиотеки (или какого-либокомпонента библиотеки). Точно также только разработчик программы может точнознать, когда можно освободить память от используемой библиотеки.Загрузка при начале выполнения программы менее экономно расходуетоперативную память, но проще реализуется, поскольку может быть полностьюавтоматизирована, а задача такой динамической загрузки может быть решенакомпоновщиком программ (редактором связей).
Для этого достаточно в заголовокпрограммы добавить перечень всех используемых в программе библиотек. Имея такойперечень, который обычно передается компоновщику в качестве одного из параметровего запуска, он может обеспечить загрузку всех библиотек в память перед началомработы основной программы.Современные системы программирования обычно допускают оба метода работыс динамическими библиотеками, а решение по выбору конкретного методапринимается разработчиком программы. В общем случае, для разных библиотек можновыбирать разные методы.
Выбор зависит от размеров библиотек и количестваобращений к их компонентам.Загрузка динамических библиотек в оперативную память, освобождение этойпамяти, а также связывание основной программы и ее данных с компонентамибиблиотек (программами и данными) выполняется динамическим загрузчиком. Этотзагрузчик входит в состав операционной системы и контролирует все обращения кдинамически загружаемым библиотекам и модулям, считает эти обращения, а также64освобождает память, когда количество действующих обращений оказывается равнымнулю. Передача функции загрузчика из системы программирования в операционнуюсистему позволила обеспечить повторное использование библиотечных компонентовпри обращении к ним нескольких различных программ. Если динамическая библиотекауже загружена в память, нет необходимости загружать ее повторно.
Загрузчик способенотслеживать двойные обращения и обеспечивать доступ к библиотечным компонентамвсем работающим программам.Выполнение функций динамическим загрузчиком возможно только в томслучае, если загружаемая библиотека или объектный модуль имеют определеннуюструктуру, содержащую в себе информацию, необходимую для трансляции адресов.Большинство современных редакторов связей могут работать в режиме формированиятаких библиотек и модулей. Непосредственная загрузка динамических объектов впамять выполняется настраивающим загрузчиком, при этом их программная частьоказывается доступной всем исполняемым программам, а часть, содержащая данныедублируется для каждой исполняемой программы так, как будто она являетсяединственной программой, использующей динамически загружаемые объекты.Формат файлов динамических библиотек полностью зависит от операционнойсистемы, он близок к формату исполняемых файлов.
В эти файлы (так же, как и встатических библиотеках) включены описания компонентов, что позволяеткомпиляторам автоматически контролировать операторы обращения к библиотечнымкомпонентам. В то же время каких-либо команд обращения к этим компонентамкомпиляторы для динамических библиотек вставить не могут.
Вместо них в программывставляются команды обращения к функциям операционной системы, которыеобеспечивают обращения к компонентам динамических библиотек. Эти команды могутвставляться автоматически, что предполагает проведение динамической загрузки вмомент запуска основной программы, либо “вручную” самим разработчикомпрограммы, что обеспечит реализацию динамической загрузки в момент реальногообращения к библиотечным компонентам. Компоненты, к которым завершены всеобращения, могут удаляться операционной системой из памяти машины. Вновь онипопадают в память только после очередного реального обращения к ним.Динамические библиотеки имеют множество преимуществ перед статическими.Их составляющие не должны включаться в состав исполняемых файлов программ, чтозначительно сокращает их размеры. Этого преимущества удается добиться за счетразработки специального механизма операционной системы, который выполняетподключение фрагментов одних программ к другим в момент их выполнения.Известным недостатком динамических библиотек является зависимостьпрограммного обеспечения от библиотечных объектов, непосредственно не связанныхс этим обеспечением, то есть зависимость программ пользователей от неизвестных имдинамических библиотек.
Для выполнения программ, основанных на динамическомподключении библиотек, необходимо принимать специальные меры, гарантирующиеналичие всех необходимых библиотечных компонентов в составе той вычислительнойсистемы, где предполагается исполнять эти программы. Одновременно возникаетзависимость самой логики работы программ от подключаемых к ней библиотек.Изменения в библиотеках осуществляются системными средствами, не зависящими отразработчиков прикладного обеспечения, а эти изменения могут влиять на работупрограмм, которые сами не менялись перед этим продолжительное время.65Это означает, что использование динамических библиотек налагаетобязательства, как на их разработчиков, так и на их пользователей.
Разработчикприкладной программы должен тщательно придерживаться правил, предложенныхразработчиками библиотек. В свою очередь, разработчики библиотек, внося вбиблиотеки изменения, должны предпринимать меры, чтобы эти измененияминимальным образом сказывались на прикладных программах, основанных напредыдущих версиях библиотеки. Одним из результатов таких мер является то, что всовременных библиотеках имеются специальные библиотечные компоненты, которыепозволяют точно определить версию данного библиотечного набора компонентов.Описанное повышение эффективности использования памяти вычислительнойсистемы происходит за счет увеличения времени выполнения программ, поскольку надинамическую загрузку приходится тратить дополнительное время.3.6.3. Основные типы библиотекНикакая современная система программирования не может обойтись безвстроенных в нее библиотечных средств.
Для широкого распространениябиблиотечных средств в программировании имеются, по крайней мере, две причины:••необходимость оказывать поддержку программам во время их исполнения навычислительной машине,потребность накапливать полезные программы и передавать их другимпользователям,нераскрываядеталейреализацииалгоритмов,запрограммированных в них.По функциональному наполнению все используемые в составе современныхсистем программирования библиотеки можно классифицировать следующим образом:•••библиотеки функций, процедур и макроопределений,библиотеки классов,библиотеки компонентов.3.6.3.1. Библиотеки функций, процедур и макроопределенийМногие программы, прошедшие компиляцию, нуждаются в поддержке во времявыполнения. Почти все языки программирования включают в себя некоторыеэлементы, реализация которых подразумевает, что во время выполнения программыдолжна обеспечиваться связь с операционной системой.