ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 24.12.2021
Просмотров: 12192
Скачиваний: 10

488 Глава 6. Уровень операционной системы
Функции подсистемы OS/2 тоже ограничены. Возможно, в будущих версиях
ее уже не будет. Она также использует подсистему Win32. Существует и подсисте-
ма MS DOS (она не показана на рисунке).
Перейдем к обсуждению служб, которые предлагает операционная система NT.
Ее интерфейс — это основное средство связи программиста с системой. К сожале-
нию, компания Microsoft не опубликовала полный список системных вызовов NT,
и кроме того, она меняет их от выпуска к выпуску. При таких обстоятельствах
практически невозможно написание программ, которые непосредственно совер-
шают системные вызовы.
Зато компания Microsoft определила набор вызовов
Win32 API (Application
Programming Interface — прикладной программный интерфейс).
Это библиотеч-
ные процедуры, которые либо совершают системные вызовы, чтобы выполнить
определенные действия, либо в некоторых случаях выполняют некоторые действия
прямо в библиотечной процедуре пользовательского пространства или подсисте-
ме Win32. Вызовы Win32 API не меняются при создании новых версий.
Однако, кроме этого, существуют вызовы NT API, которые могут менятся в но-
вых версиях NT. Так как вызовы Win32 API задокументированы и более стабиль-
ны, мы сосредоточим наше внимание именно на них, а не на системных вызовах NT.
В системах Win32 API и UNIX применяются совершенно разные подходы. В UNIX
все системные вызовы общеизвестны и формируют минимальный интерфейс:
удаление хотя бы одного из них изменит функционирование операционной систе-
мы. Подсистема Win32 обеспечивает очень полный интерфейс. Здесь часто одно
и то же действие можно выполнить тремя или четырьмя разными способами. Кро-
ме того, Win32 включает в себя много функций, которые не являются системными
вызовами (например, копирование целого файла).
Многие вызовы Win32 API создают объекты ядра того или иного типа (файлы,
процессы, потоки, каналы и т. п.). Каждый вызов, создающий объект ядра, возвра-
щает вызывающей программе результат, который называется
идентификатором
(handle).
Этот идентификатор впоследствии может использоваться для выпол-
нения операций над объектом. Для каждого процесса существует свой идентифи-
катор. Он не может передаваться другому процессу и использоваться там (де-
скрипторы файла в UNIX тоже нельзя передавать другому процессу). Однако при
определенных обстоятельствах можно продублировать идентификатор, передать
его другим процессам и разрешить им доступ к объектам, которые принадлежат
другим процессам. Каждый объект имеет связанный с ним дескриптор защиты,
который сообщает, кому разрешено или запрещено совершать те или иные опера-
ции над объектом.
Операционную систему NT иногда называют объектно-ориентированной, по-
скольку оперировать с объектами ядра можно только с помощью вызова процедур
(функций API) по их идентификаторам. С другой стороны, она не обладает таки-
ми основными свойствами объектно-ориентированной системы, как наследование
и полиморфизм.
Win32 API имеется и в системе Windows 95/98 (а также в операционной систме
Windows СЕ), правда, с некоторыми исключениями. Например, Windows 95/98
не имеет защиты, поэтому те вызовы API, которые связаны с защитой, просто
возвращают код ошибки. Кроме того, для имен файлов в NT используется набор

Примеры операционных систем
489
Да
Нет
Нет
Нет
Нет
Да
Нет
Intel 80x86
Нет
Нет
Да
Да
Да
Да
Да
Да
Да
80x86, Alpha
Да
Да
символов Unicode, которого нет в Windows 95/98. Существуют различия в пара-
метрах для некоторых вызовов API. В системе NT, например, все координаты эк-
рана являются 32-битными числами, а в системе Windows 95/98 используются
только младшие 16 битов (для совместимости с Windows 3.1). Существование на-
бора вызовов Win32 API на нескольких разных операционных системах упрощает
перенос программ между ними, но при этом кое-что удаляется из основной систе-
мы вызовов. Различия между Windows 95/98 и NT изложены в табл. 6.7.
Таблица 6.7.
Некоторые различия между версиями Windows
Характеристика Windows 95/98 NT 5.0
Win32 API
Полностью 32-битная система
Защита
Отображение защищенных файлов
Отдельное адресное пространство для каждой
программы MS-DOS
Plug and Play
Unicode
Процессор
Многопроцессорная поддержка
Реентерабельная программа (допускающая повторное
вхождение) внутри операционной системы
Пользователь может сам написать некоторые важные Да Нет
части операционной системы
Примеры виртуальной памяти
В этом разделе мы поговорим о виртуальной памяти в системах UNIX и NT. С точки
зрения программиста они во многом сходны.
Виртуальная память UNIX
Модель памяти в системе UNIX довольно проста. Каждый процесс имеет три сег-
мента: код, данные и стек, как показано на рис. 6.26. В машине с линейным адрес-
ным пространством код обычно располагается в нижней части памяти, а за ним
следуют данные. Стек помещается в верхней части памяти. Размер кода фиксиро-
ван, а данные и стек могут увеличиваться или уменьшаться. Такую модель легко
реализовать практически на любой машине. Она используется в операционной
системе Solaris.
Более того, если машина содержит страничную память, то все адресное про-
странство может быть разбито на страницы, а пользовательские программы этого
не знают. Единственное, что им будет известно, — то, что размер программы может
превышать размер физической памяти машины. Системы UNIX, у которых нет
страничной организации памяти, обычно перекачивают целые процессы между
памятью и диском, чтобы сколь угодно большое число процессов работало в режи-
ме разделения времени.

4 9 0 Глава 6. Уровень операционной системы
Адрес
OxFFFFFFFF
Стек
Данные
Код
Рис. 6.26. Адресное пространство одного процесса UNIX
Описание, данное выше (виртуальная память с подкачкой страниц по требова-
нию), в целом подходит для Berkeley UNIX. Однако Sysytem V (и Solaris) имеет
некоторые особенности, позволяющие пользователям управлять виртуальной па-
мятью. Самой важной является способность процесса отображать файл или часть
файла на часть его адресного пространства. Например, если файл в 12 Кбайт ото-
бражается на виртуальный адрес 144 К, то в ячейке с адресом 144 К будет нахо-
диться первое слово этого файла. Таким образом, можно осуществлять ввод-вывод
файла без применения системных вызовов. Поскольку размер некоторых фай-
лов может превышать размер виртуального адресного пространства, можно ото-
бражать не весь файл, а только его часть. Чтобы осуществить отображение, сначала
нужно открыть файл и получить дескриптор
файла fd
(file descriptor). Дескриптор
используется для идентификации файла, который нужно отобразить. Затем про-
цесс совершает вызов
paddr=nmap(virtual_address.1ength.protection,f 1 ags.fd,fI1e_offset)
который отображает
length,
начиная с
file_offset
в файле, в виртуальное адресное
пространство, начиная с
virtualjxddress.
Параметр
flags
требует, чтобы система
выбрала виртуальный адрес, который затем возвращается в
paddr.
Отображаемая
область должна содержать целое число страниц и должна быть выровнена в гра-
ницах страницы. Параметр
protection
определяет разрешение на чтение, запись
и выполнение (в любой комбинации). Отображение можно в дальнейшем удалить
с помощью команды unmap.
В один и тот же файл можно одновременно отображать несколько процессов.
Есть два варианта разделения общих страниц. В первом случае разделяются все
страницы, поэтому записи, призводимые одним процессом, видны всем другим
процессам. Эта возможность обеспечивает между процессами тракт с высокой про-
пускной способностью. Во втором случае страницы разделяются всеми процессами
до тех пор, пока какой-нибудь процесс не изменит их. Как только один из процессов
пытается произвести запись в страницу, он получает ошибку защиты, в результате
чего операционная система выдает ему копию этой страницы, в которую можно
производить запись. Такая схема используется в том случае, когда для каждого из
нескольких процессов нужно создать иллюзию, что только он отображается в файл.
Виртуальная память Windows NT
В NT каждый пользовательский процесс имеет свое собственное виртуальное
адресное пространство. Длина виртуального адреса составляет 32 бита, поэтому
каждый процесс имеет 4 Гбайт виртуального адресного пространства. Нижние

Примеры операционных систем 491
2 Гбайт предназначены для кода и данных процесса; верхние 2 Гбайт разрешают
ограниченный доступ к памяти ядра. Исключение составляют версии NT для
предприятий, в которых разделение памяти может быть другим: 3 Гбайт — для
пользователя и 1 Гбайт — для ядра. Виртуальное адресное пространство с подкач-
кой страниц по требованию содержит страницы фиксированного размера (4 Кбайт
на машине Pentium II).
Каждая виртуальная страница может находиться в одном из трех состояний:
она может быть
свободной
(free),
зарезервированной
(reserved) и
выделенной
(committed). Свободная страница в текущий момент не используется, а обраще-
ние к ней вызывает ошибку из-за отсутствия страницы. Когда процесс начинается,
все его страницы находятся в свободном состоянии до тех пор, пока программа и
начальные данные не будут отображены в свое адресное пространство. Если код
или данные отображены в страницу, то такая страница является выделенной. Обра-
щение к выделенной странице будет успешным, если страница находится в основ-
ной памяти. Если страница отсутствует в основной памяти, то произойдет ошибка
и операционной системе придется вызывать нужную страницу с диска. Виртуаль-
ная страница может находиться и в зарезервированном состоянии. Это значит, что
эта страница недоступна для отображения до тех пор, пока резервирование не бу-
дет отменено. Помимо атрибутов состояния страницы имеют и другие атрибуты
(например, указывающие на возможность чтения, записи и выполнения). Верхние
64 Кбайт и нижние 64 Кбайт памяти всегда свободны, чтобы можно было отыски-
вать ошибки указателей (неинициализированные указатели часто равны 0 или -1).
Каждая выделенная страница имеет теневую страницу на диске, где она хра-
нится при отсутствии ее в основной памяти. Свободные и зарезервированные стра-
ницы не имеют теневых страниц, поэтому обращения к ним вызывают ошибки из-
за отсутствия страницы (система не может вызвать страницу с диска, если этой
страницы нет на диске). Теневые страницы на диске сгруппированы в один или
несколько страничных файлов. Операционная система следит, в какую часть ка-
кого страничного файла отображается каждая виртуальная страница. Файлы с тек-
стами программ имеют теневые страницы; для страниц данных используются спе-
циальные страничные файлы.
NT, как и System V, позволяет отображать файлы прямо в области виртуально-
го адресного пространства. Если файл был отображен в адресное пространство,
его можно считывать или записывать путем обычных обращений к памяти.
Отображаемые в память файлы реализуются так же, как другие выделенные
страницы, только теневые страницы могут находиться в файле на диске, а не в стра-
ничном файле. В результате, когда файл отображается, версия в памяти может не
совпадать с версией на диске (из-за последних записей в виртуальное адресное
пространство). Однако когда отображение файла удаляется, версия на диске об-
новляется.
NT позволяет отображать два и более процессов в одном файле одновременно,
возможно, в разных виртуальных адресах. Путем считывания слов из памяти и за-
писи слов в память процессы могут взаимодействовать друг с другом и передавать
данные в обоих направлениях с достаточно высокой скоростью, поскольку ника-
кого копирования не требуется. Разные процессы могут обладать разными разре-
шениями на доступ. Все процессы, использующие отображенный файл, разделяют

4 9 2 Глава 6. Уровень операционной системы
одни и те же страницы, поэтому изменения, произведенные одним из процессов,
видны всем остальным процессам, даже если файл на диске еще не был обновлен.
Win32 API содержит ряд функций, которые позволяют процессу открыто управ-
лять виртуальной памятью. Самые важные из этих функций приведены в табл. 6.8.
Все они работают в области, состоящей либо из одной страницы, либо из двух или
более страниц, последовательно расположенных в виртуальном адресном простран-
стве.
Таблица 6.8.
Основ, ые функции API для управления виртуальной памятью
в системе Windows NT
Функция API Значение
VirtualAlloc Резервация или выделение области
VirtualFree Освобождение области или снятие выделения
VirtualProtect Изменение типа защиты на чтение/запись/выполнение
VirtualQuery Запрос о состоянии области
VirtualLock Делает область памяти резидентной (то есть запрещает разбиение
на страницы в ней)
VirtualUnlock Снимает запрет на разбиение на страницы
CreateFileMapping Создает объект отображения файла и иногда приписывает ему имя
MapViewOfFile Отображает файл или часть файла в адресное пространство
UnmapViewOfFile Удаляет отображенный файл из адресного пространства
OpenFileMapping Открывает ранее созданный объект отображения файла
Первые четыре функции очевидны. Следующие две функции позволяют про-
цессу делать резидентной область памяти размером до 30 страниц и отменять это
действие. Это качество может понадобиться программам, работающим в режиме
реального времени. Операционная систма устанавливает определенный предел,
чтобы процессы не становились слишком поглощающими. В системе NT также
имеются функции API, которые позволяют процессу получать доступ к виртуаль-
ной памяти другого процесса (они не указаны в табл. 6.8).
Последние 4 функции API предназначены для управления отображаемыми
в память файлами. Чтобы отобразить файл, сначала нужно создать объект отобра-
жения файла с помощью функции
CreateFileMapping.
Эта функция возвращает
идентификатор (handle) объекту отображения файла и иногда еще и вводит в сис-
тему файлов имя для него, чтобы другой процесс мог использовать объект. Две
функции отображают файлы и удаляют отображение соответственно. Следующая
функция нужна для того, чтобы отобразить файл, который в данный момент ото-
бражен другим процессом. Таким образом, два и более процессов могут разделять
области своих адресных пространств.
Эти функции API являются основными. На них строится вся остальная систе-
ма управления памятью. Например, существуют функции API для размещения и
освобождения структур данных в одной или нескольких «кучах». «Кучи» исполь-
зуются для хранения структур данных, которые создаются и разрушаются. «Кучи»
не занимаются «сборкой мусора», поэтому пользовательское программное обеспе-
чение само должно освобождать блоки виртуальной памяти, которые уже не нуж-