Операционная система UNIX. Руководство программиста

     

Как ОС UNIX работает с разделяемыми библиотеками?


Теперь, когда Вы понимаете, за счет чего разделяемые библиотеки позволяют экономить память, необходимо изучить, как ОС UNIX работает с ними. Это позволит понять, почему использование разделяемых библиотек может иногда привести к увеличению расхода памяти.

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

Разделяемая библиотека сборки - это фактически то же самое, что и архивная библиотека. Каждый из ее элементов (обычно это законченный объектный файл) содержит имена некоторых функций и данных в своей таблице имен. Этот файл просматривается редактором внешних связей, когда разделяемая библиотека сборки указывается при компиляции или редактировании связей программы. Просмотр производится с целью разрешения внешних ссылок. Однако, как уже отмечалось, редактор связей не копирует элементы разделяемой библиотеки, разрешающие внешние ссылки, в объектный файл программы. Вместо этого редактор, найдя эти определения, помещает в объектный файл информацию, идентифицирующию их местонахождение в библиотеке. В результате создается специальная секция выполняемого файла, которая обозначается .lib. См. также раздел Что такое разделяемая библиотека? выше.

Разделяемая библиотека выполнения похожа на файл a.out(4). ОС

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


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

Секция .data разделяемой библиотеки выполнения не может одновременно использоваться несколькими процессами. Каждый процесс, обращающийся к данным из библиотеки, получает свою собственную область, то есть непрерывный участок адресного пространства, идентичный секции .data разделяемой библиотеки выполнения. Чтобы не происходило нежелательного взаимодействия процессов, разделяющих общую секцию команд, эти процессы не разделяют данные и область стека.

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

Таблица переходов ld(1) является средством статического редактирования связей, поэтому он должен назначить адреса всем именам, которые встре- чаются в процессе редактирования. Разделяемая библиотека сборки используется для разрешения внешних ссылок на имена из разделя- емой библиотеки. В полученном выполняемом файле все такие имена получат свои адреса.

Что произойдет, если текст разделяемой библиотеки будет изменен, в результате чего изменится адрес какого-либо имени из библиотеки? Если бы это была архивная библиотека, ничего бы не произошло, поскольку в выполняемый файл была бы включена копия того элемента библиотеки, в котором имя определяется. Хотя это была бы копия старого варианта, такой файл можно было бы выполнять и в дальнейшем. Однако, если бы выполняемый файл создавался с разделяемой библиотекой, подобное изменение библиотеки могло бы отразиться на нем неблагоприятно. Действительно, в таком файле нет самого содержимого библиотеки, а есть только информация, указывающая его местонахождение. После реорганизации библиотеки ее структура могла бы измениться, в результате чего ОС UNIX, выполняя файл, предоставила бы ему не тот вариант библиотеки, который нужен данному файлу. Таким образом, чтобы Ваши программы работали правильно, их связи пришлось бы редактировать после каждого изменения библиотеки.



Для предотвращения подобных эффектов ОС UNIX, работая с разделяемой библиотекой, использует таблицу переходов. Имена связываются с абсолютными адресами входов в этой таблице. Эти адреса остаются неизменными при модификации содержимого библиотеки. Каждый элемент таблицы переходов содержит команду безусловного перехода по адресу, соответствущему имени. Таким образом, ссылки на имена из библиотеки разрешаются с помощью элементов таблицы переходов, а не с помощью собственно содержимого библиотеки.

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






Содержание раздела