Иллюстрированный самоучитель по теории операционных систем

Динамические библиотеки

При сборке DLL из нескольких объектных модулей программист должен предоставить DEF-файл (пример 3.10). В этом файле содержится перечисление символов, экспортируемых библиотекой (в отличие от обычных, "архивных" библиотек, набор этих символов не обязательно равен объединению наборов экспортных символов всех включенных в библиотеку объектов), а также некоторые другие параметры.

Например, можно указать, что DLL имеет функции инициализации и терминации. Эти функции могут запускаться как при первой загрузке библиотеки (INITGLOBAL), так и при подключении библиотеки очередной программой (INITINSTANCE). Можно также управлять разделением сегмента данных DLL – применять общий сегмент данных для всех программ, использующих библиотеку, или создавать свою копию для каждой программы.

Пример 3.10. DEF-файл из примеров кода VisualAge C++ V3.0:

LIBRARY REXXUTIL INITINSTANCE LONGNAMES
PROTMODE
DESCRIPTION 'REXXUTIL Utilities – (c) Copyright IBM Corporation 1991
DATA MULTIPLE NONSHARED STACKSIZE 32768
EXPORTS
SYSCLS = SysCls @1 SYSCURPOS = SysCurPos
@2 SYSCURSTATE = SysCurState @3 SYSDRIVEINFO = SysDrivelnfo @4
SYSDRIVEMAP = SysDriveMap @5
SYSDROPF0NCS = SysDropFuncs @6
SYSFILEDELETE = SysFileDelete @7
SYSFILESEARCH = SysFileSearch @8
SYSFILETREE – SysFileTree @9
SYSGETMESSAGE = SysGetMessage 010
SYSINI = Syslni 011
SYSLOADFUNCS = SysLoadFuncs @12
SYSMKDIR = SysMkDir @13
SYSOS2VER = SysOS2Ver 014
SYSRMDIR = SysRmDir @15
SYSSEARCHPATH = SysSearchPath @16
SYSSLEEP = SysSleep @17
SYSTEMPFILENAME = SysTempFileName @18
SYSTEXTSCREENREAD = SysTextScreenRead @19
SYSTEXTSCREENSIZE = SysTextScreenSize La20
SYSGETEA = SysGetEA @21
SYSPUTEA = SysPutEA @22
SYSWAITNAMEDPIPE = SysWaitNamedPipe @23

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

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

Понятно, что рассчитывать на устойчивую работу всех тридцати программ можно только при условии, что все три версии библиотеки полностью совместимы снизу вверх не только по набору вызовов и их параметров, но и по точной семантике каждого из этих вызовов. Последнее требование иногда формулируют как bug-for-bug compatibility (корректно перевести это словосочетание можно так: полная совместимость не только по спецификациям, но и по отклонениям от них).

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

Требование "совместимости с точностью до ошибок" – это лишь полемически заостренная формулировка требования контролируемости поведения кода. Из вышеприведенных соображений понятно, что нарушения такой контролируемости представляют собой проблему, которая, не будучи так или иначе разрешена, может серьезно усложнить работу администраторов системы и приложений.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.