Операционные системы. Управление ресурсами

       

Установка межмодульных связей при динамической компоновке



Рисунок 4.1. Установка межмодульных связей при динамической компоновке


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

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

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

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

Системный вызов: mod_handle = loadModule (mod_name); загружает модуль из файла с указанным именем. Если указанного модуля нет в памяти, ОС производит загрузку его из файла, если же модуль в памяти уже есть, ОС просто увеличивает на 1 счетчик использований этого модуля. Вызов должен возвращать манипулятор модуля, используемый для его идентификации во всех последующих операциях с ним.

Возможна модификация этого вызова: mod_handle = getModuleHandle (mod_name); получить манипулятор модуля: если модуль уже есть в памяти, вызов возвращает его манипулятор (и увеличивает счетчик использований), если нет - возвращает признак ошибки. В последнем случае программа может либо загрузить модуль вызовом loadModule, либо перейти на такую свою ветвь, которая не предусматривает обращений к данному модулю.

Системный вызов: freeModule (mod_handle); выгружает модуль. ОС уменьшает на 1 счетчик использования модуля, если этот счетчик обратился в 0, освобождает память.

Системный вызов: vaddr = getProcAddress (mod_handle, proc_name); возвращает виртуальный адрес процедуры с заданным именем в уже загруженном модуле. Все дальнейшие обращения к данной процедуре программа производит по этому адресу.



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