Что такое разделяемые библиотеки в с. Статические и динамические библиотеки - лекция

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

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

Некоторые старые системы, например, Burroughs MCP , Multics , также имеют только один формат для исполняемых файлов, независимо от того, являются ли они общими. Они имеют файлы общей библиотеки того же формата, что и исполняемые файлы. Это дает два основных преимущества: во-первых, для каждого из них требуется только один загрузчик, а не два (наличие отдельного загрузчика приносит дополнительную сложность). Во-вторых, он также позволяет использовать исполняемые файлы в качестве разделяемых библиотек, если у них есть таблица символов . Типичные форматы комбинированных исполняемых и совместно используемых библиотек: ELF и Mach-O (оба в Unix) и (Windows).

В некоторых более старых средах, таких как 16-битная Windows или MPE для HP 3000 , в е с общей библиотекой допускались только данные на основе стека (локальные), или другие существенные ограничения были наложены на разделяемой библиотеки.

Разделяемая память [ | ]

библиотеки может совместно быть в памяти вместе c процессами , а также на диске. Если используется виртуальная память, процессы будут выполнятся в физической странице ОЗУ, которая отображается в разные адресные пространства процессов. Это имеет свои преимущества. Например, в системе OpenStep приложения часто имеют размер всего несколько сотен килобайт и быстро загружаются; большая часть их а находилась в библиотеках, которые уже были загружены операционной системой для других целей.

Программы могут осуществлять совместное использование ОЗУ с помощью независимого а , как в Unix , что приводит к сложной, но гибкой архитектуре. Это гарантирует, что с помощью различных приемов, таких как предварительное отображение адресного пространства и резервирование страниц для каждой разделяемой библиотеки, имеет большую вероятность совместного использования. Третьим вариантом является одноуровневое хранилище , используемое IBM System/38 и его преемниками.

В некоторых случаях разные версии разделяемых библиотек могут вызывать проблемы, особенно когда библиотеки разных версий имеют одинаковые имена файлов, и используется для разных приложений, установленных в системе, для каждой требуется определённая версия. Такой сценарий известен как DLL hell , названный в честь Windows и OS/2 DLL . Большинство современных операционных систем после 2001 года имеют методы очистки для устранения таких ситуаций или использования «частных» библиотек для конкретных приложений.

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

Использование разделяемых библиотек и/или DLL (в данном случае разница между ними не принципиальна) предполагает ту или иную форму сборки в момент загрузки: исполняемый модуль имеет неразрешенные адресные ссылки и имена библиотек, которые ему нужны. При загрузке эти библиотеки подгружаются и ссылки разрешаются. Проблема здесь в том, что при Подгрузке библиотеки ее нужно переместить, перенастроив абсолютные адресные ссылки в ее коде и данных (см. Главу 3). Если в разных процессах библиотека будет настроена на разные адреса, она уже не будет разделяемой (рис. 5.14)! Если разделяемые библиотеки могут иметь неразрешенные ссылки на другие библиотеки, проблема только усугубляется - к перемещаемым ссылкам добавляются еще и внешние.

Рис. 5.14 . Конфликтующие адреса отображения DLL

В старых системах семейства Unix, использовавших абсолютные загружаемые модули формата a.out , разделяемые библиотеки также поставлялись в формате абсолютных модулей, настроенных на фиксированные адреса. Каждая библиотека была настроена на СВОЙ адрес. Поставщик новых библиотек должен был согласовать этот адрес с разработчиками системы. Это было весьма непрактично, поэтому разделяемых библиотек было очень мало (особенно если не считать те, которые входили в поставку ОС).

Более приемлемое решение этой проблемы реализовано в OS/2 2.x и Win32 (обе эти архитектуры являются развитием систем с единым адресным пространством). Идея состоит в том, чтобы выделить область адресов под загрузку DLL и отображать эту область в адресные пространства всех процессов. Таким образом, все DLL, загруженные в системе, видны всем (рис. 5.15).

Большинство современных версий Unix поддерживают разделяемые библиотеки. Разделяемые библиотеки позволяют изъять из исполняемого файла библиотечные функции; в результате в памяти системы хранится единственная копия библиотеки, к которой обращаются все процессы. Это заметно уменьшает размер исполняемых файлов, но может несколько увеличить нагрузку, когда приложение запускается в первый раз или когда происходит первое обращение к библиотечной функции. Еще одно преимущество разделяемых библиотек заключается в том, что при обновлении библиотеки не требуется исправлять связи с библиотекой в каждой программе, которая использует эту библиотеку. (Здесь мы исходим из предположения, что количество и типы аргументов библиотечных функций не изменились).

ОС Linux предоставляет возможность указать компилятору cc , следует ли использовать разделяемые библиотеки в программе или нет.

7.7. Распределение памяти

Стандарт ISO C определяет три функции, с помощью которых производится распределение памяти:

    Функция malloc выделяет заданное количество байтов памяти. Выделенный объем памяти не очищается.

    Функция calloc выделяет пространство для заданного количества объектов определенного размера. Выделенный объем памяти заполняется нулевыми байтами.

    Функция realloc перераспределяет выделенную ранее память, увеличивая или уменьшая ее объем. Увеличение выделенного ранее объема может сопровождаться перемещением участка памяти в новое место. Кроме того, участок памяти, который оказывается между концом ранее выделенного блока и новым концом, не инициализируется.

#include

void *malloc (size_t size);

void *calloc (size_t nobj, size_t size);

void *realloc (void *ptr, size_t newsize);

/* все три функции возвращают непустой указатель в случае успеха, NULL – в случае ошибки */

void free (void *ptr);

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

Все три функции возвращают нетипизированный указатель void * , поэтому, подключив к программе заголовочный файл , который содержит прототипы функций, мы не должны выполнять явное приведение типов при присваивании значений функций типизированным указателям.

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

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

Обратите внимание, что последний аргумент функции realloc определяет новый размер требуемой области, а не разницу между новым и старым размерами. В особом случае, когда в аргументе ptr передается пустой указатель, функция realloc ведет себя подобно функции malloc , выделяя область памяти размером newsize .

Функции распределения памяти обычно реализуются на основе системного вызова sbrk . Этот системный вызов расширяет (или усекает) область динамической памяти (кучи) процесса (рис. 7.3). Пример типичной реализации функций malloc и free приводится в разделе 8.7 [Керниган, Ритчи].

Хотя системный вызов sbrk может как увеличивать, так и уменьшать объем памяти процесса, большинство версий malloc и free никогда не уменьшают его. Освобождаемое пространство становится доступным для последующего распределения, и, как правило, не возвращается ядру – оно помещается в пул свободной памяти функции malloc .

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

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

Другие возможные ошибки, которые могут оказаться фатальными – попытка освобождения блока памяти, уже освобожденного ранее, а также передача функции free указателя, который не был получен от одной из трех функций выделения памяти. Если процесс вызывает функцию malloc , но забывает вызвать функцию free , то объем используемой памяти начинает непрерывно увеличиваться; это называют утечкой памяти. Если процесс не будет возвращать ставшие ненужными блоки памяти с помощью функции free , то объем адресного пространства, занимаемого процессом, будет медленно увеличиваться до тех пор, пока свободное пространство не закончится. Это может привести к снижению производительности системы из-за лишних обращений к файлу подкачки.

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

Знаете ли Вы, что такое мысленный эксперимент, gedanken experiment?
Это несуществующая практика, потусторонний опыт, воображение того, чего нет на самом деле. Мысленные эксперименты подобны снам наяву. Они рождают чудовищ. В отличие от физического эксперимента, который является опытной проверкой гипотез, "мысленный эксперимент" фокуснически подменяет экспериментальную проверку желаемыми, не проверенными на практике выводами, манипулируя логикообразными построениями, реально нарушающими саму логику путем использования недоказанных посылок в качестве доказанных, то есть путем подмены. Таким образом, основной задачей заявителей "мысленных экспериментов" является обман слушателя или читателя путем замены настоящего физического эксперимента его "куклой" - фиктивными рассуждениями под честное слово без самой физической проверки.
Заполнение физики воображаемыми, "мысленными экспериментами" привело к возникновению абсурдной сюрреалистической, спутанно-запутанной картины мира. Настоящий исследователь должен отличать такие "фантики" от настоящих ценностей.

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

Это мы видим на примере СТО и ОТО, превратившихся в своеобразный вид религии, управляющей наукой и общественным мнением. Никакое количество фактов, противоречащих им, не может преодолеть формулу Эйнштейна: "Если факт не соответствует теории - измените факт" (В другом варианте " - Факт не соответствует теории? - Тем хуже для факта").

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

Эксперимент на то и эксперимент, что он есть не изощрение мысли, а проверка мысли. Непротиворечивая внутри себя мысль не может сама себя проверить. Это доказано Куртом Гёделем.

Разделяемая библиотека позволяет использовать содержащиеся в ней символы в нескольких фильмах без копирования этих символов в библиотеки фильмов. Из-за этого объекты разделяемой библиотеки называются ресурсами (Assets). При этом разделяемая библиотека используется как внешний файл и не добавляется к создаваемому (или редактируемому) фильму.

Применение разделяемых библиотек целесообразно, например, в следующих случаях:

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

Flash MX поддерживает два типа разделяемых библиотек:

  • Run-time - разделяемая библиотека времени выполнения; символы, входящие в такую библиотеку, доступны для совместного использования несколькими фильмами, однако редактироваться такие символы могут только непосредственно в фильме-источнике;
  • Author-time - библиотека, разделяемая на время разработки; символы, входящие в такую библиотеку, доступны для совместного использования несколькими фильмами, причем разрешается редактировать содержимое библиотеки в любом фильме-совладельце.

Чтобы ресурсы разделяемой библиотеки могли быть доступны в фильмах, размещенных на удаленном сайте, Flash-файл с этой библиотекой должен быть экспортирован в формат SWF и загружен на Web-сайт.

Замечание

В предыдущей версии Flash поддерживается только разделяемая библиотека времени выполнения.

Чтобы создать разделяемую библиотеку типа Run-time, необходимо:

  1. Определить ее ресурсы (входящие в нее символы) в отдельном фильме.
  2. Разрешить экспорт разделяемых символов.
  3. Указать URL сайта, на котором будет размещена библиотека.
  4. Экспортировать Flash-файл с этой библиотекой в формат SWF и выгрузить на Web-сайт.

Чтобы получить возможность использовать символы разделяемой библиотеки Run-time в других фильмах («совладельцах»), необходимо в каждом из них создать ссылку на разделяемые символы.

Теперь рассмотрим перечисленные выше шаги более подробно.

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

  1. Выберите в списке символ, который вы хотите сделать «разделяемым».
  2. В контекстном меню символа выберите команду Linking (Связывание).
  3. В открывшемся диалоговом окне Symbol Linkage Properties (Параметры связывания символа), рис. 10.12, установите флажок Export for runtime sharing (Разрешить экспорт на время выполнения).
  4. В текстовом поле Identifier введите имя (идентификатор) символа, под которым он будет экспортирован в фильм-совладелец; хотя по умолчанию в поле заносится библиотечное имя символа, если оно содержит пробелы, удалите их.
  5. В текстовом поле URL введите интернет-адрес фильма-источника (то есть SWF-файла с разделяемой библиотекой).
  6. Если экспортируемый символ следует использовать непосредственно с первого кадра фильма-совладельца, установите флажок Export in first frame.
  7. Если экспортируемый символ следует сделать доступным в сценарии на ActionScript, установите флажок Export for ActionScript.

Рис. 10.12. Диалоговое окно установки параметров символов разделяемой библиотеки

Чтобы использовать ресурсы разделяемой библиотеки Run-time в фильме-совладельце, требуется выполнить следующие действия:

  1. Откройте библиотеку этого фильма, выбрав в меню Window команду Library.
  2. В раскрывающемся меню библиотеки выберите команду New Symbol; в результате на экране появится диалоговое окно Create New Symbol (Создание нового символа), центральная часть которого аналогична по формату диалоговому окну Symbol Linkage Properties (рис. 10.13).
  3. В текстовом поле Identifier введите имя символа, который следует импортировать в фильм-совладелец.
  4. В текстовом поле URL введите интернет-адрес фильма-источника.

Рис. 10.13. Диалоговое окно для установки параметров разделяемого символа

Применение разделяемой библиотеки другого типа - Author-time - позволяет изменять (точнее, заменять) содержимое символов в редактируемом FLA-файле. При этом следует иметь в виду, что имя символа уже «зашито» в редактируемом фильме. Поэтому символ, импортируемый из разделяемой библиотеки, как бы подменяет собой исходный символ, сохраняя его имя. Если импортируемый символ содержит вложенные символы, они также будут импортированы.

Чтобы связать символ, подлежащий «подмене», с соответствующим символом из разделяемой библиотеки, необходимо:

  1. В редактируемом файле откройте окно библиотеки, выбрав в меню Window команду Library.
  2. В списке символов выберите символ, подлежащий «подмене», щелкните на нем правой кнопкой и в контекстном меню выберите команду Properties.
  3. В нижней части открывшегося диалогового окна. (см. рис. 10.13), в группе элементов Source (Источник) щелкните на кнопке Browse (Просмотр), и в окне Window Explorer выберите FLA-файл с нужной библиотекой; в результате на экране появится еще одно окно - Select Source Symbol (Выбор символа-источника), которое содержит список всех символов разделяемой библиотеки (рис. 10.14).


Рис. 10.14. Диалоговое окно Select Source Symbol

  1. Выберите в списке нужный символ и щелкните на кнопке ОК; это приведет к закрытию окна и изменению формата элементов управления в группе Source (рис. 10.15):
    • станет доступен флажок Always update before publishing (Всегда обновлять перед публикацией) - если он установлен, то символ в редактируемом фильме будет автоматически заменяться символом из разделяемой библиотеки при публикации фильма;
    • в текстовом поле File появится путь к файлу с разделяемой библиотекой;
    • в текстовом поле Symbol Name появится имя символа из разделяемой библиотеки;
    • станет доступна кнопка Symbol, щелчок на которой открывает диалоговое окно Select Source Symbol, приведенное на рис. 10.14.


Рис. 10.15. Формат элементов управления в группе Source после связывания символов

Замечание

Фильм может использовать ресурсы нескольких разделяемых библиотек любого типа.

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

  1. Выбрать в меню File (Файл) основного окна Flash команду Open As Library (Открыть как библиотеку).
  2. С помощью окна Windows Explorer указать Flash-файл с нужной библиотекой; в результате на столе будет открыто окно этой библиотеки.
  3. Скопировать нужные символы из окна библиотеки в библиотеку фильма (или непосредственно на стол).

Содержимое такой библиотеки, подобно содержимому общей и постоянной библиотек, не может быть изменено из фильма-клиента (то есть из фильма, использующего ее ресурсы).



В продолжение темы:
Android

Популярная социальная сеть ВКонтакте позволяет находить новых друзей и держать контакт со всеми близкими. Помимо этого, каждый пользователь может делиться собственными...