Совместно используемые библиотеки

Совместное использование может быть с другой степенью структурированности. Если программа будет запущена дважды, то большинство операционных систем автоматически организуют совместное использование текстовых страниц, чтобы в памяти была только одна копия.
Текстовые страницы всегда используются в режиме только для чтения, поэтому проблем не возникает. В зависимости от операционной системы каждый
процесс может получить собственную частную копию страниц с данными или же они могут совместно использоваться и иметь пометку «Только для чтения». Если какой- нибудь процесс изменяет страницу данных, для него будет создана частная копия, то есть будет использована копия, пригодная для записи.

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

Вместо этого должна использоваться общая технология совместно используемых (общих) библиотек, которые в Windows называются динамически подключаемыми библиотеками (Dynamic Link Libraries (DLL)). Чтобы сделать идею совместно используемой библиотеки более понятной, рассмотрим сначала традиционную компоновку. При компоновке программы в команде компоновщику указывается один или несколько объектных файлов и, возможно, несколько библиотек, как, например, в команде UNIX

ld *.o -lc -lm

которая компонует все файлы с расширением .o (object), имеющиеся в текущем каталоге, а затем сканирует две библиотеки, /usr/lib/libc.a и /usr/lib/libm.a. Любые функции, вызываемые в объектных файлах, но не присутствующие в них (например, printf), называются неопределенными внешними функциями и выискиваются в библиотеках. Если они найдены, то их включают в исполняемый двоичный файл. Любые вызываемые, но не присутствующие в них функции также становятся неопределенными внешними функциями. К примеру, функции printf требуется функция write, поэтому, если функция write еще не включена, компоновщик будет ее разыскивать и, как только найдет, включит в двоичный файл. Когда компоновка завершится, исполняемый двоичный файл, записываемый на диск, будет содержать все необходимые функции. Имеющиеся в библиотеке, но невостребованные функции в него не включаются. Когда программа загружается в память и выполняется, в ней содержатся все необходимые ей функции.

Теперь предположим, что обычная программа использует 20-50 Мбайт функций, относящихся к графике и пользовательскому интерфейсу. Статически скомпонованные сотни программ со всеми этими библиотеками будут тратить впустую громадный объем дискового пространства, а также пространства оперативной памяти, как только они будут загружены, поскольку у системы не будет способа узнать о том, что она может использовать эти библиотеки как общие. И тут на сцену выходят совместно используемые библиотеки. Когда программа скомпонована с учетом совместного использования библиотек (что несколько отличается от статической компоновки), вместо включения реально вызываемых функций компоновщик включает небольшую подпрограмму-заглушку, которая в процессе исполнения привязывается к вызываемой функции. В зависимости от системы или от особенностей конфигурации совместно используемые библиотеки загружаются либо при загрузке программы, либо когда присутствующие в них функции вызываются в первый раз. Разумеется, если совместно используемая библиотека уже загружена другой программой, то нет нужды загружать ее повторно — именно в этом и заключается весь смысл. Следует заметить, что при загрузке или использовании общей библиотеки вся библиотека разом в память не считывается.

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

Сделать исполняемые файлы меньшими по объему и сэкономить пространство памяти помогает еще одно преимущество совместно используемых библиотек: если функция, находящаяся в общей библиотеке, обновляется с целью устранения ошибки, то перекомпилировать программу, которая ее вызывает, не нужно. Старые двоичные файлы сохраняют свою работоспособность. Это свойство приобретает особое значение для коммерческого программного обеспечения, код которого не доставляется клиенту. Например, если корпорация Microsoft находит и исправляет ошибку, влияющую на безопасность системы в некой стандартной библиотеке DLL, программа обновления — Windows Update — загрузит новую DLL и заменит ею старую библиотеку, и все программы, использующие данную DLL, будут при следующем запуске автоматически использовать новую версию.

Но совместно используемые библиотеки пришли к нам с одной небольшой проблемой, требующей решения. Эта проблема показана на рис. 3.24. Здесь отображены два процесса, совместно использующие библиотеку размером 20 Кбайт (предположим, что каждый ее блок занимает 4 Кбайт). Но библиотека в каждом процессе располагается по разным адресам, по-видимому, потому что сами программы не совпадают по размеру. В процессе 1 библиотека размещается, начиная с адреса 36 К; в процессе 2 ее размещение начинается с адреса 12 К. Предположим, первое, что должна сделать первая функция библиотеки, — перейти в библиотеке к адресу 16. Если библиотека не использовалась совместно, она может быть перемещена на лету в процессе загрузки, поэтому переход (в процессе 1) может быть осуществлен на виртуальный адрес 36 К + 16. Следует заметить, что физический адрес оперативной памяти, по которому размещается библиотека, не имеет значения, пока все страницы отображаются с виртуальных на физические адреса аппаратурой диспетчера памяти — MMU.

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

Процесс 1 Оперативная Процесс 2

память

Рис. 3.24. Общая библиотека, используемая двумя процессами

процессом 2 (по адресу 12 К), команда перехода вынуждена осуществить его на адрес 12 К + 16, а не на адрес 36 К + 16. В этом и заключается небольшая проблема. Одним из путей ее решения является использование копии при записи и создании новых страниц для каждого процесса, использующего общую библиотеку, и перемещение их на лету во время создания. Но эта схема, разумеется, дискредитирует всю цель совместного использования библиотеки.

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

3.5.7.

<< | >>
Источник: Э. ТАНЕНБАУМ Х. БОС. СОВРЕМЕННЫЕ ОПЕРАЦИОННЫЕ СИСТЕМ Ы 4-е ИЗДАНИЕ. 2015

Еще по теме Совместно используемые библиотеки:

  1. 14.6. Организация взаимодействия библиотек
  2. 14.8. Авторское право в деятельности библиотек
  3. Приложение СЛОВАРЬ ТЕРМИНОВ, ИСПОЛЬЗУЕМЫХ В АКТАХ ИНФОРМАЦИОННОГО ЗАКОНОДАТЕЛЬСТВА
  4. 3.3. Научно-технические методы и средства, используемые для лабораторного исследования объектов
  5. Телос, живая библиотека Приветствую вас, друзья.
  6. Издания Ф. В. Булгарина и Н. И. Греча и журнал «Библиотека для чтения»
  7. 3.2. Научно-технические средства и методы криминалистической техники, используемые для обнаружения, фиксации и изъятия доказательств
  8. Статья 305. Право на ознакомление с личными бумагами, переданными в фонд библиотек или архивов
  9. 12.3.3. Совместное путешествие
  10. ДЕЯТЕЛЬНОСТЬ СОВМЕСТНАЯ
  11. 3. Проекты совместного внедрения
  12. О недостатках совместного сна
  13. Статья 1130. Договор о совместной деятельности
  14. § 3. Право общей совместной собственности
  15. Статья 1131. Форма и условия договора о совместной деятельности
  16. § 3. Право общей совместной собственности
  17. Раздел XV. Обязательства из совместной деятельности
  18. Статья 368. Право общей совместной собственности
  19. Глава 77 - Гражданского кодекса Совместная деятельность