C:\OpaKQtion M.
ф.
Systams\fiuthoK5>
Б о н д з р а м и о ^
Е.
Г.
К з ч и о
б7э
eiCcoj
£ T g 1
M. Ф. Бондаренко, Е. Г. Качко
•пврационныЕ систвты
1
ЧИТАЛЬНИП
^ Л1ГЕРД ™бл1отеы, «Компания СМИТ» Харьков 2006
УДК 519.68 ББК 65.262 Б 81
як
Рекомендовано Міністерством освіти і науки України навчальний посібник для студентів вищих навчальних закладів {лист № від р.)
Рецензенти: А.Г. Р у т к а с , д-р мат. н а у к , проф. ( к а ф е д р а ЕОМ Х Н У ) ; Л . В . К у р п а , д-р т е х н . н а у к , п р о ф . ІІТУ «ХПІ»
Б 81
Бондаренко М. Ф., К а ч к о О. Г. О п е р а ц і й н і с и с т е м и : Н а в ч . п о с і б н и к . — X . : ТОВ «Компанія С М И Ч , 2006. — 4 4 4 с. 966-8530-53-5 У навчальному посібнику викладено основні принципи побудови та використання сучасних операційних систем. Розглянуто методи керування пам'яттю, процесами, потоками, зовнішніми пристроями та їх використання під час практичного програмування. Рекомендується студентам денної та заочної форм навчання спеціаль ностей напрямку «Комп'ютернінауки». УДК 5X9.68 ББК 65.262
І8ВМ 9 6 6 - 8 5 3 0 5 3 - 5
© М. Ф. Бондаренко, О. Г. Качко, 2006 © ТОВ «Компанія СМІТ», 2006
СОДЕРЖАНИЕ
Введение
6
1. ОБЗОР О П Е Р А Ц И О Н Н Ы Х СИСТЕМ 1.1. Роль и задачи о п е р а ц и о н н ы х систем 1.2. История развития о п е р а ц и о н н ы х систем 1.3. Функции т и п и ч н ы х о п е р а ц и о н н ы х систем — 1.4. Влияние программного обеспечения с о т к р ы т ы м кодом и интернет на проектирование ОС 1.5. Механизмы п о д д е р ж к и модели «Клиент — сервер», мобильных устройств 1.6. Свойства операционных систем 1.7. Классификация ОС 1.8. Вопросы и задачи 2. ОСНОВНЫЕ П Р И Н Ц И П Ы Р А З Р А Б О Т К И ОПЕРАЦИОННЫХ СИСТЕМ 2.1. Методы структуризации 2.2. Методология я д р а 2.3. Абстракции, процессы и ресурсы 2.4. Необходимость A P I и промежуточного программного обеспечения (middleware) 2.5. Потребности п р и л о ж е н и й и э в о л ю ц и я программного и аппаратного обеспечения 2.6. Понятие режимов я д р а и пользователя. Переключение м е ж д у р е ж и м о м я д р а и пользователя 2.7. Организация устройств 2.8. Прерывания. Методы и р е а л и з а ц и и 2.9. Интерфейсы I/O. П р я м о й доступ к п а м я т и 2.10. Списки устройств и очереди драйверов 2.11. Стратегии буферизации д л я ДУ 2.12. Вопросы и задачи 3. ПАРАЛЛЕЛИЗМ 3.1. Понятие параллельного и с п о л н е н и я 3.2. Аппаратная поддержка многозадачного р е ж и м а 3.3. Состояние и д и а г р а м м ы состояний д л я процессов 3.4. Структуры, используемые д л я з а д а н и я процессов 3.5. Переключение контекстов 3.6. Обработка прерываний п р и п а р а л л е л ь н о м исполнении 3.7. Проблемы у п р а в л е н и я одновременно и с п о л н я е м ы м и процессами 3
9 9 10 21 24 25 26 27 29 30 30 33 42 43 46 47 63 65 70 72 76 77
79 79 82 94 99 103 104 105
3.8. Модели и механизмы синхронизации 3.9. К о м м у н и к а ц и я между процессами 3.10. Особенности мультипроцессорных систем (спин блокировка, реентерабельность) 3.11. Вопросы и задачи
114 124 127 128
4. ПЛАНИРОВАНИЕ И Д И С П Е Т Ч Е Р И З А Ц И Я 4.1. Операции планирования и диспетчеризации 4.2. Алгоритмы планирования 4.3. П о л и т и к а планирования 4.4. Процессы, потоки и задания 4.5. Вопросы и задачи
130 130 132 135 138 163
5. ОБЗОР СРЕДСТВ СИНХРОНИЗАЦИИ ПОТОКОВ И ПРОЦЕССОВ Д Л Я ОС WINDOWS 5.1. Синхронизация потоков. Атомарный доступ 5.2. Синхронизация потоков. Критическая секция 5.3. Использование объектов ядра д л я синхронизации 5.4. Ф у н к ц и и о ж и д а н и я и объекты синхронизации 5.5. Вопросы и задачи
165 166 170 175 190 190
6. У П Р А В Л Е Н И Е ПАМЯТЬЮ 6.1. Виртуальная память 6.2. Аппаратные средства управления памятью 6.3. Алгоритмы и средства управления памятью 6.4. Обзор ф у н к ц и й для управления памятью 6.5. Вопросы и задачи
191 192 195 218 223 257
7. У П Р А В Л Е Н И Е УСТРОЙСТВАМИ 259 7.1. Управление устройствами 259 7.2. Управление операциями I/O д л я символьных устройств 260 7.3. Управление операциями I/O д л я блочных устройств ... 262 7.4. Р е ж и м ы управления вводом - выводом 272 7.5. Абстрактные понятия различий устройств (абстрагирование от различий). Виртуальные внешние устройства 273 7.6. Стратегии буферизации и кэширования 273 7.7. Прямой доступ к памяти 274 7.8. Вопросы и задачи 275 8. ФАЙЛОВЫЕ СИСТЕМЫ 8.1. Основные понятия 8.2. Компоненты файловой системы 4
277 277 281
8.3. Содержимое и структура каталогов (словарей) 282 8.4. Методы работы файловой системы. Виртуальные файловые системы 284 8.5. Монтирование и демонтирование ФС 292 8.6. Стандартные методы реализации 297 8.7. Примеры файловых систем 298 8.8. Работа с устройствами 333 8.9. Работа с файлами 338 8.10. Вопросы и задачи 358 9. ДРАЙВЕРЫ 9.1. Определение драйвера 9.2. История создания драйверов 9.3. Требования и особенности драйверов для WINDOWS 2000 и выше 9.4. Использование установленных драйверов в пользовательских п р и л о ж е н и я х 9.5. Разработка драйверов 9.6. Пример драйвера и программы для использования драйвера 9.7. Вопросы и задачи
360 360 361
10. ЯЗЫКИ СЦЕНАРИЕВ 10.1. Язык сценариев и их роль 10.2. Основные системные команды ОС WINDOWS 10.3. Написание сценариев, передача параметров 10.4. Выполнение сценариев 10.5. Влияние языков сценариев на программирование... 10.6. Вопросы и задачи
406 406 407 409 415 418 419
11. СТРУКТУРНАЯ ОБРАБОТКА И С К Л Ю Ч Е Н И Й 11.1. Обработка завершения 11.2. Обработка исключений 11.3. Вопросы и задачи
420 421 425 429
363 369 375 390 405
Приложение 1. Переключение режимов работы процессора ... 430 Приложение 2. Переключение задач, поля и флаги
433
Приложение 3. Исключения IA-32
434
Приложение 4. Структуры д л я VFS
435
Литература
438
Предметный указатель
439
ВВЕДЕНИЕ
Курс «Системное программирование и операционные системы» является базовым курсом в цикле подготовки специалистов в области программного обеспечения. Разработкой системных программ всегда занимались программисты высшей квалификации. 8а время построения и использования операционных систем накоплен огромный опыт их разработки, создано множество прекрасных алгоритмов. Таких, например, как алгоритм, реализующий дисциплину LRU, который с помощью нескольких битов позволяет эффективно определить наиболее долго неиспользуемый элемент; алгоритм близпецов, используемый для быстрого выдечеиия памяти с минимальной фрагментацией, и др. Целью данного курса является не только изучение принципов построения операционных систем и изучения наиболее интересных алгоритмов для реализации этих принципов, но и привитие интереса к созданию новых принципов и алгоритмов. Авторы надеются, что слушатели данного курса смогут квалифицированно и творчески использовать все возможности, предоставляемые современными операционными системами, развивать эти возможности и решать новые проблемы, которые постоянно ставит жизнь перед средствами вычислительной техники. Таким образом, если курс «Алгоритмические языки и программирование» учит студентов составлять простые алгоритмы и программы, то курс «Системное программирование и операционные системы» позволяет максимально приблизиться к профессиональному программированию. Этот курс учит выполнять количественную оценку алгоритмов и программ, выбирать наилучшее решение из многих, создавать и использовать современные про-
граммные модули типа динамических библиотек, строить многопроцессные и многопоточные приложения и управлять ими. В этом курсе студенты рассматривают «изюминки» в построении операционных систем, такие к а к управление внешними устройствами на физическом уровне, синхронизация процессов в сложном мире одновременного в ы п о л н е н и я м н о ж е с т в а процессов и потоков, исключения взаимной блокировки процессов. После изучения курса студенты смогут ответить на вопросы, почему операционная система «виснет» и к а к избежать этого неприятного состояния. Многие скажут, что можно быть хорошим программистом, не зная этих вещей, и будут правы. Но в любом программистском коллективе должны быть С п е ц и а л и с т ы особые, к а к говорят, «от бога», которые знают, где искать ошибки, к а к их исправить, как решить ту или другую проблему и поставить диагноз при любой болезни компьютера и программы. Эта дисциплина к а к раз и предназначена для того, чтобы открыть в себе такие способности и сделать первые шаги к своему будущему в этом направлении. По операционным системам есть море и н ф о р м а ц и и . Т а к , поисковый сайт Google.com в ответ на запрос «Операционные системы» выдает 1 700 ООО ссылок. Выбор из этого массива наиболее необходимой и полезной информации является очень трудной задачей и для современного специалиста, и тем более для студентов, учитывая, что последние начнут активно работать с информацией через несколько лет после изучения курса. При определении содержания курса за основу взята программа курса «Операционные системы» [1]. И з л а г а я отдельные вопросы, можно построить этот курс к а к теоретический, как практический или рассмотреть и те, и другие положения. Так к а к курс читается студентам на втором году обучения и предполагает подготовку бакалавров, изложение его к а к чисто теоретического, по мнению авторов, нецелесообразно. С другой стороны, изложение исключительно практического использования средств системного программирования, например, функций WinApi, не способствует воспитанию творческого специалиста. Вот почему данный курс в целом имеет практическую направленность, но в нем рассматриваются не только функции для решения разных классов задач, но и методы решения этих задач. В частности, в разделе о синхронизации рассмотрены механизмы синхронизации, теория и практика создания и использования семафоров, способы преодоления тупиков и т.д. 7
Следующей проблемой, которую необходимо было решить при создании учебного пособия, стал выбор платформы из двух наиболее популярных (WINDOWS, UNIX). Здесь нет однозначного решения, тик как система WINDOWS сегодня более востребована; с другой стороны, изучение UNIX-подобной системы позволяет глубже освоить эту систему из-за открытости кода. Для изложения основных алгоритмов и принципов управления памятью, процессами, внешними устройствами, построения файловых систем авторы использовали ядро системы LINUX и его описание, например, [14]. При рассмотрении практических вопросов применения функций ОС используются системные вызовы ОС WINDOWS. Объем материала, изложенного в учебном пособии, превышает тот, который может быть рассмотрен в одном двухсеместровом курсе. Здесь есть обязательные и необязательные по классификвции рааделы [1]. Данное учебное пособие может использоваться не только студентами начальных курсов, но и на протяжении всех лет обучения. Практически все программы, представленные в пособии, являются завершенными программами и поэтому могут использоваться для решения практических задач. Наряду с простыми программами здесь рассмотрены принципы построения и использования драйверов, работа с диском на физическом уровне в 32-битном режиме, принципы построения и практического использования файловых систем и т.д. Данное учебное пособие написано авторами на основании многолетнего опыта чтения курсов «Системное программирование^ «Системное программирование и операционные системы», •Системное программное обеспечение».
1. ОБЗОР О П Е Р А Ц И О Н Н Ы Х СИСТЕМ
Цели изучения раздела: 1 Разобраться с целями и функциями современных О С . 2. Изучить этапы развития ОС от простейших систем пакетной о б р а ботки до современных ОС. 3. Проанализировать компромиссные решения, которые надо принимать при проектировании О С . 4. Описать функции современных ОС с точки зрения удобства работы, эффективности и масштабируемости. 5 Рассмотреть сетевые, клиент-серверные, распределенные ОС и их отличия от однопользовательских О С . 6. Рассмотреть проблемы с безопасностью ОС и возможные методы их решения. 7. Объяснить, как программное обеспечение с открытым кодом и интернет влияют на проектирование ОС
1.1. Роль и задачи операционных систем Под операционной системой (ОС) [2] п о н и м а ю т к о м п л е к с управляющих и о б р а б а т ы в а ю щ и х п р о г р а м м , к о т о р ы й предназначен для наиболее эффективного и с п о л ь з о в а н и я ресурсов вычислительной системы, о р г а н и з а ц и и н а д е ж н ы х в ы ч и с л е н и й и упрощения работы п о л ь з о в а т е л я с в ы ч и с л и т е л ь н о й с и с т е м о й . ОС является промежуточным звеном м е ж д у а п п а р а т у р о й и приложениями пользователя, обеспечивает пользователя удобными средствами для п р и м е н е н и я в н е ш н и х у с т р о й с т в , д л я э ф ф е к тивного использования м о щ н о с т е й п р о ц е с с о р о в , в к л ю ч е н н ы х в вычислительную систему, д л я у д а л е н н о й п е р е д а ч и д а н н ы х по сетям, включая локальные, к о р п о р а т и в н ы е сети и интернет. 9
С точки зрения вычислительной системы ОС должна распределять процессоры, память, устройства и данные между приложениями, конкурирующими за эти ресурсы. ОС должна управлять всеми перечисленными выше ресурсами вычислительной м а ш и н ы так и м образом, чтобы обеспечить максимальную эффективность ее функционирования. Д л я определения ф у н к ц и й современных ОС и их задач ниже рассмотрена история р а з в и т и я вычислительных систем и соответствующая эволюция ОС. По мере развития вычислительных систем увеличивается сложность ОС. Если ранее ОС начинала создаваться после создания вычислительного устройства с нуля, то современные ОС создаются параллельно с созданием вычисл и т е л ь н ы х систем. Это обеспечивается за счет использования готовых модулей, разработанных для других вычислительных систем, применения аппаратно-независимых я з ы к о в программирования для создания большинства модулей ОС и развитой теории создания ОС. В данном разделе курса рассматриваются основные положения теории и п р а к т и к и разработки ОС.
1.2. История развития операционных систем 1.2.1.Управление исполнением программ. Пакетная о б р а б о т к а
П р и использовании первых в ы ч и с л и т е л ь н ы х систем программист полностью управлял выполнением своих программ. Это управление сводилось к вводу программы, заданной на внешних носителях, запуску программы, ее завершению и установке новой программы. Такой режим использования требовал от программиста постоянного присутствия при выполнении программы даже в том случае, если не выполнялась ее отладка. Д л я автоматизации прохождения программ был разработан с п е ц и а л ь н ы й модуль ( п а к е т н ы й монитор), который выполнял загрузку очередной программы, ее запуск, завершение и запуск новой программы, если она была в пакете. Алгоритм пакетной обработки: while (есть задания в пакете){ Формирование исполнимого файла (трансляция, компоновка); if (нет ошибок){ Выполнение программы;
10
) e!sa{ Обработка ошибки; Пропуск данных для текущего задания;
} ) В этом случае в памяти постоянно хрпнпгся пикетный монитор. В современных операционных системах пакетный режим поддерживается с помощью командных файлов, которые позволяют не только задать порядок выполнения приложений, но и определить потоки ввода-вывода, обеспечить выполнение очередного приложения в зввисимости от кода возврата предыдущего приложения, выполнять разветвления и циклы. Особенно развит язык задания командных файлов для операционных систем класса UNIX (язык SHELL). Мы использовали командные файлы для трансляции, компоновки и загрузки в оттадчик ассемблерных программ. Более подробно использование командных файлов рассмотрено в разделе 10 этого учебника. Недостатки
пакетного
режима:
• применим только для заданий, требующих небольшого времени выполнения. В противном случае время ожидания завершения последующих заданян может быть недопустимо большим; • если однв из программ зациклилнеь в связи с ошибкой в алгоритме или в исходных данных, остальные программы пакета никогда не завершатся. Этот недостаток устраняется в пакетах, для которых можно указать предельное время выполнения; • наличие диалога между пользователем и программой очень нежелательно, так как это делает зависимым общее время выполнения пакета от реакции пользователя на отдельные компоненты пакета; • тпк кик запуск компилятора и компоновщика входит в функции монитора, могут использоваться только те компиляторы, которые были заложены при разработке монитора, поэтому усложняется расширение системы. Основной недостаток первых систем пакетной обработки: пакеты должны были передаваться на исполнение компьютеру с внешнего устройства этого же компьютера, не существовало возможности дистанционной передачи команд и данных. В середине 60-х годов фирмой IBM был разработан способ для дистанционной передачи заданий на исполнение (Remote Job Entry — RJE). 11
Т а к к а к п р о г р а м м а у п р а в л е н и я и с п о л н е н и е м програм должна находиться в оперативной п а м я т и одновременно с испо. няемой программой, возникает проблема з а щ и т ы этих програмт ных модулей от взаимного в л и я н и я . К а ж д ы й из модулей долж( работать только «со своей»> памятью и не изменять содержим< «чужой» п а м я т и . И т а к , первая ф у н к ц и я операционной системы — управлеш запуском и завершением приложения. 1.2.2. Управление внешними устройствами
По м е р е п о в ы ш е н и я производительности процессора в< более «узким местом» становились операции ввода-вывода, кот рые д л я первых процессоров входили в их систему команд, flj уменьшения потерь времени, связанных с выполнением операци ввода-вывода, используется два способа. 1 способ. Н а р я д у с использованием медленных устройст таких к а к клавиатура и принтер, применяются быстрые устро] ства, например, магнитные диски (МД). Перед исполнением пр граммы исходные данные записываются на быстрые устройств, к а ж е м , на МД. Результаты исполнения программы тоже з а п и и ваются на это устройство. Программа выполняется на быстро компьютере. Отдельный медленный, а значит, относительно д ш е в ы й компьютер, используется для перезаписи данных. 2 способ. Д л я внешнего устройства разрабатывается спец] а л ь н ы й процессор (контроллер), который выполняет операцк ввода-вывода. В этом случае основной процессор может в то и в р е м я в ы п о л н я т ь другую работу. Д л я с и н х р о н и з а ц и и работ основного процессора и контроллера (данные могут использоват ся только после завершения операции ввода и могут изменяты только после завершения операции вывода д л я текущего состо н и я данных) необходимы специальные средства. В современных вычислительных системах обычно испол зуется второй способ. В этом случае модуль управления вводо! выводом фактически должен выполнить следующие операци По запросу операции ввода-вывода задать информацию об этс операции (используемое устройство, адрес памяти для обме! данными, их размер и т.д.) в виде, понятном контроллеру устро ства, и передать эту информацию. По завершении операции ввод вывода обработать код завершения. Модуль для управления оп р а ц и я м и ввода-вывода д л я конкретных устройств в современнь 12
ОС называется драйвером. Современные драйверы поддерживают 2 режима управления. Синхронный режим используется, когда программа ждет завершения операции ввода-вывода, очередной оператор программы выполняется только после окопчппия этой операции (см. 8-9-2). Этот, самый простой с точки зрения программиста режим, является неэффективным с точки зрения использования вычислительной системы, так как время ожидания может быть достаточно большим- Асинхронный режим (еж. 8.9.3) предполагает продолжение выполнения программы после запуска операции ввода-вывода. Модуль упревлення, работающий в этом режиме, должен обеспечить возможность программного отслеживания момента завершений операции ввода-вывода для его правильного использования в программе. Данный режим является более сложным с точки зрения программиста, во более эффективным с точки зрения времени выполнения приложения. В современных ОС модуль управления вводом называют менеджером ввода-вывода (I/O-Manager), его функции включают в себя не только формирование запроса и обработку завершения, но и передачу этого запроса между драйверами, а также передачу сообщений прп завершении работы драйвера очгредного уровня. Использование промежуточных драйверов обеспечивает независимость программ от используемых устройств. Программист может использовать одни и те же функции длн ввода-вывода данных для дискет, жестких дисков. CD, USB, сетевых устройств и т.д. Режим работы вычислительной системы, при котором обеспечиваются параллельное выполнение операций ввода-вывода и работа основного процессора, называется мультипрограммированием. Название связано с тем, что при выполнении операций ввода-вывода для одной программы центральный процессор используется для вычислений в другой программе. Таким обрезом, в памяти одновременно хранятся несколько программ. Очевидно, что производительность системы существенно зависит от их специфики. Если одна из программ в основном выполняет операции ввода-вывода, а другая использует мало времени для этих операций, такие программы хорошо согласуются. В режиме одновременного выполнения можно параллельно выполнять не только независимые программы (процессы), ио и функции одной про граммы (потоки), если эти функции используют разные устройства или не одновременно обращаются к устройствам ввода-вывода(сл. 4.4). Для переключения между программами или потоками 13
одной программы используется программный модуль, который в современных ОС называется Диспетчером процессов/потоков (Process Manager). Модуль управления вводом-выводом и диспетчер процессов/ потоков должны находиться в оперативной памяти одновременно с исполняемыми программами, для которых обеспечивается параллельное выполнение; проблема защиты этих программных модулей от взаимного влияния остается актуальной. Каждый из модулей должен работать только «со своей» памятью и не изменять содержимое «чужой» памяти. Итак, очередные функции операционной системы управление вводом-выводом и переключение м е ж д у программами в многопрограммном режиме. 1.2.3. Многопользовательский режим Сегодня все привыкли к режиму применения компьютера, когда пользователь задает информацию с помощью клавиатуры (интерактивный режим). В этом случае основное время затрачивается не ввод этой информации, центральный процессор в это время простаивает. Так, первые телетайпы, которые использовались для ввода данных, обеспечивали скорость вводе 11 символов в секунду. Применение современных клавиатур существенно не увеличило скорость, так как она ограничена возможностями человека. Контроллер клавиатуры позволяет передавать процессору не каждый символ, а целиком введенную строку, что при необходимости делает возможным исправление заданных символов до их передачи для обработки. Использование мощных процессоров для вычислений при работе пользователя в интерактивном режиме является неэффективным. Для увеличения производительности вычислительной системы один процессор использовался для работы с несколькими пользователями. Каждому пользователю система выделяет отрезок (квант) времени. Если пользователей не очень много и используется мощная вычислительная система, то у каждого пользователя создается иллюзия монопольной работы с этой системой. Здесь возникают дополнительные проблемы, связанные с обслуживанием пользователей: авторизация пользователя, приоритетное или бесприоритетное обслуживание, распределение общих устройств, например, принтеров, между пользователями и т.д. И, хотя с появлением мощных персональных компьютеров проблема многопользовательского режима 14
стала менее актуальной, тем не менее эта задача по-прежнему стоит на повестке дня; кроме того, аналогичные задачи приходится решать при использовании сетей. Как и в предыдущих случаях, актуальной остается задача ващиты от вваимного влияния всех взаимодействующих и конкурирующих модулей. Режим использования процессора в режиме квантования времени называется режимом разделения времени. Д л я современных опереционных систем режим квантования используется при реботе запущенных приложений (процессов) и их отдельных функций (потоков). Таким обрезом, следующая функция операционной системы управление процессами и потоками в режиме квантования времени. Эта функция выполняется модулем управления процессами (Process manager). 1.2.4. Управление памятью Для безопасного использования многопрограммного и многопользовательского режимов необходимо координировать распределение памяти между отдельными приложениями и модулями операционной системы. Эту координацию выполняет модуль управления памятью. Этот модуль также управляет распределением памяти для нужд самой ОС. В связи с тем, что в какой-то момент времени оперативной памяти для исполняемых программ может не хватить, другие программы могут быть вытеснены на жесткий диск. Посте повторной их загрузки адреса данных и функций могут изменяться- Опереционная система должна обеспечить правильный доступ к данным после их повторной загрузки и правильный вызов функций- Таким образом, код в программе должен быть позиционно независимым, в противном случае модули ОС должны корректировать его в случае изменения адреса загрузки. Современные процессоры обеспечивают позиционную независимость кода ка аппаратном уровне. Например, для процессоров типа Intel в команде перехода задается ресстояггие между адресом команды, следующей за командой перехода, п меткой, куда надо перейти. В этом случае перемещение программы не влечет за собой необходимость изменения команд перехода. Модуль управления памятью должен также обеспечить эффективный и простой метод выделения — освобождения памяти првложепиям, доступ ко всему имеющемуся адресному пространству, защиту в зависимости от прав доступа к памяти. 15
Модуль управления памятью (Memory manager) является одним из самых с л о ж н ы х модулей ОС. От эффективности алгоритмов у п р а в л е н и я п а м я т ь ю существенно з а в и с и т эффективность ОС в целом. 1.2.5. Системы реального времени (СРВ)
П р и м е н я ю т с я д л я управления р а з л и ч н ы м и техническими объектами, т а к и м и , например, к а к станок с числовым программн ы м у п р а в л е н и е м . Х а р а к т е р н о й особенностью т а к и х систем я в л я е т с я ограничение на предельно допустимое время, в течение которого д о л ж н а быть выполнена та или и н а я программа, у п р а в л я ю щ а я объектом — в противном случае может произойти авария. Т а к и м образом, критерием эффективности д л я систем реального времени является их способность выдерживать заранее заданные интервалы времени между запуском программы и получением результата (управляющего воздействия). Это время называется временем реакции системы, а соответствующее свойство системы — реактивностью. Следующая ф у н к ц и я ОС, которая характерна д л я систем реального времени, — обеспечение выполнения сервисных функций в течение заранее заданного интервала времени. Системы реального времени в данном пособии не рассматриваются. 1.2.6. Работа в сети. Серверные операционные системы
В конце 70-х годов стали бурно развиваться компьютерные сети — к а к локальные, так и глобальные, что в немалой степени связано с удешевлением компьютеров. Б ы л создан стек (набор) протоколов 1 T C P / I P , не только используемый сейчас в сети интернет, но и очень популярный в локальных сетях. Первой операционной системой, в которой эти протоколы были полноценно р е а л и з о в а н ы , стала U N I X . Т а к и м образом, UNIX иэ обычной системы разделения времени стала сетевой системой — системой, способной взаимодействовать по сети с другими ОС. Наличие локальных сетей, прежде всего, обеспечивает возможность совместного использования дорогостоящих компонен1 Протокол — правила взаимодействия 2-х или более сторон, которые включают в себя необходимые структуры данных, выполняемые функции и способ обращения к этим функциям.
16
тов вычислительной системы. В этом случае компоненты общего пользования сосредотачиваются на сервере (жесткие диски, принтеры), доступ к ним осуществляется с ПК через сетевое оборудование. ОС обеспечивает управление регистрацией пользователей, формирование и надежную транспортировку пакетов в сети. Так как в сети могут быть компьютеры с резными оперециоиными системами, ОС должна поддерживать стандартные протоколы для формирования н передачи пакетов. Очередная функция операционной системы — поддержка реботы с локальной, корпоративной и глобальной сетью INTERNET. Назначение серверной ОС — управление приложениями, которые обслуживают всех пользователей корпоративной сети, а нередко и внешних пользователей. К таким приложениям относятся: • совремевные системы упревления базами данных; • средства управления сетями и средства анализа событий в сети; • службы каталогов ^хранилище учетных записей всех пользователей сети, клиентов, серверов и приложений, дополненных средствами конфигурирования сети, подключения удаленных пользователей и управления удаленными компьютерами); • средства обмена сообщениями, • групповые реботы; а корпоративные брандмауэры; • серверы приложений резличного назначения. Для таких ОС наиболее важными являются требования надежности п производительности. Сетевые ОС должны обязательно обеспечивать возможность кластеризации, т.е. использования однотипных компьютеров для выполнения одной и той же задачи и делящих между собой нагрузку. Особое значение приобретают возможности дублирования и резервирования информации. Так как серверы, как превило, ле выключаются и работают непрерывно, необходимо обеспечение возможности подключения новой аппаратуры и программного обеспечения без перезагрузки системы. В связи с тем, что курсы, связанные с сетями и сетевыми ОС, читаются отдельно, в данном учебнике сетевые ОС не рессматриваются. 17
1.2.7.Обеспечение услуг безопасности В современных условиях всестороннего использования вычислительных систем, в том числе и для электронного документооборота, проблема безопасности данных становится все более актуальной. Обеспечение услуг безопасности начинается с регистрации пользователя. С каждым пользователем ОС связывает его учетную запись, в которой задаются права пользователя. С помощью политик безопасности определяются правила задания и смены паролей, блокирования учетных записей и т.д. Если позволяет файловая система, для каждого ее компонента (файла, папки, логического диска) могут быть установлены права и режимы доступа. В ОС встроены современные криптографические алгоритмы, которые позволяют в любом приложении выполнять формироввнне цифровой подписи 1 , шифрование данных и файлов. Операционная система может обеспечивать возможность прозрачного шифровзкия 2 файлов и папок. Такое шифроеение, например, выполняется при использовании файловой системы EFS. Для обеспечения возможности использоввния современных криптографических методов ОС содержит средства создания центров сертификации для управления ключами. Следующая функция операционной системы обеспечение услуг безопасности. Так как изучается специальный курс по защите информации, вопросы обеспечения услуг безопасности современными операционными системами в данном учебнике не рассматриваются.
1.2.8. Поддержка многопроцессорной обработки Современные серверы, как правило, являются многопроцессорными системами. Такие системы обычно состоят из набора запоминающих устройств и нескольких центральных процессоров, работающих под управлением одной ОС. Все процессоры обычво
1 Цифровая подпигь — аиялог обычной подписи. Вычисляется для данных, которые подписываются, поэтому с изменением данных изменяется цифровая подоись, что гнрантирует целостность подписываемых данных. Так как цифровал подпись является функцией личного ключ» подписывающего, то никто не может поддедпть его подпись без наличия этого ключа, что обеспечивает подлинность данных. Для проверки подписи используется открытый ключ, который могут иметь все. кто должен проверять подлинность подписи. Шифрован не пазы вя ют прозрачным, если оно производится автоматически перед злпитью ни носитель и раппифрояка выполняется лвтомятпчески при гчптыBflnun данных с носителя при иллнчии ключа и ппроля достуоя к ключу.
18
имеют доступ к любой области п а м я т и любого запоминающего устройства. Для обеспечения максимальной производительности таких систем операционная система должна эффективно выполнять распараллеливание потоков самой операционной системы и пользователей. При распараллеливании в многопроцессорной системе существенно у с л о ж н я ю т с я проблемы с и н х р о н и з а ц и и . Покажем это на простом примере. Пусть процессор записывает данные, обновленные данные находятся в кэше этого процессора и переписываются в оперативную память не сразу. К а к обеспечить использование этих данных другим процессором? Очередная функция операционных систем — поддержка многопроцессорной обработки. Современные операционные системы поддерживают многопроцессорную работу. Так к а к ОС UNIX используется достаточно длительное время для больших вычислительных систем (mainframe), как правило, я в л я ю щ и х с я многопроцессорными, она допускает одновременную работу с 256 и более процессорами. ОС фирмы Microsoft использовались до недавнего времени только для персональных ЭВМ, для которых поддержка многопроцессорности была не актуальной. Сближение по вычислительной мощности компьютеров, на которых используются оба типа ОС, привело к тому, что современные ОС фирмы Microsoft (после WINDOWS 98) также поддерживают многопроцессорность. Операционная система WINDOWS 2003 может работать с системами с числом процессоров не более 32 Многопроцессорная обработка может быть обеспечена в двух режимах: • Симметричная система ( s y m m e t r i c multiprocessing — SMP) — все потоки могут выполняться на любом процессоре, т.е. все процессоры рассматриваются к а к одинаковые. Все процессоры разделяют одно адресное пространство с точки зрения его доступности всем процессорам. Заметим, что в т а к и х системах достоверность данных обеспечивается на аппаратном уровне. Именно такой режим реализован в WINDOWS. Заметим, что возможность доступа к любой области памяти действительно обеспечивается т а к и м и системами. Но время доступа к памяти зависит от места этой памяти. Так, время доступа к «своей» памяти значительно меньше, чем время доступа к «чужой». Такое свойство памяти называется NUMA (Non-Uniform 1
Это количество процессоров связано с тем, что для задания маски используемых процессоров достаточно 32-битного числа.
19
Memory Access) — неодинаковый доступ к памяти. Поэтому ОС для обеспечения максимальной производительности должна учитывать и этот фактор. • Несимметричная система {asymmetric multiprocessing — AS MP) — операционная система выбирает один процессор для выполнения потоков ядра (master processor), а остальные процессоры используются для потоков пользовательских приложений. Операционная система, которая поддерживает многопроцессорность в симметричном режиме, должна обеспечить возможность выполнения любого потока приложения на любом из доступных процессоров, в том числе потоков одного приложения. В этом случае требуются н а д е ж н ы е средства синхронизации. Только такой режим использования обеспечивает увеличение быстродействия системы с увеличением числа процессоров (масштабирование). 1.2.9. Поддержка 64-битных процессоров В настоящее время широко внедряются 64-битные процессоры. Это не только расширение адресного пространства и увеличение скорости выполнения команд, но и использование новых принципов выполнения программ. На смену мнимому параллельному выполнению (режим разделения времени, например) приходит истинное распараллеливание. Модули ОС, зависящие от процессора. должны быть написаны на языке 64-битного процессора, остальные модули в наиболее полпой мере должны учитывать все его возможности, и параллельное выполнение, в первую очередь. Существуют ОС, которые используются исключительно для 64-битных процессоров (AIX), современные ОС поддерживают работу с процессорами втого класса. 1.2.10. Интерфейс между ОС и пользовательскими приложениями Для обеспечения возможности использования функций ОС в пользовательских программах применяются специальные функции, которые называются системными вызовами (СВ). Системные вызовы являются промежуточным звеном между пользовательским режимом и режимом ядра (в LINUX используется термин «оберточная функция»). В этих функциях выполняется проверка правильности параметров и выполняется вызов функций модулей ОС. 20
Эти функции позволяют наиболее эффективно выполнять такие операции, как управление распределением памяти, управление файлами, синхронизация и др. Фактически при использовании для этих целей функций языков высокого уровня эффективность снижается, так как все эти функции вызывают соответствующие функции ОС. Множество всех системных вызовов ОС называется программным интерфейсом ОС (Application P r o g r a m m i n g I n t e r f a ce — API). Для вызова системных функций (системных вызовов) в некоторых ОС используются специальные команды. Так, в DOS для вызова системной ф у н к ц и и использовалась к о м а н д а прерывания естественного хода выполнения программы (команда INT 21Н), где 21Н задает шестнадцатеричный номер обработчика прерывания. Сама вызываемая ф у н к ц и я задавалась номером, который записывался в регистр ЕАХ. Д л я современных ОС системный вызов не отличается от вызова обычных ф у н к ц и й . Пример системного вызова для WINDOWS — ф у н к ц и я CreateFile. Пример системного вызова для UNIX подобных систем — ф у н к ц и я Open. Существуют стандарты д л я определения требований к A P I . К таким стандартам относятся I E E E ' s P o r t a b l e Operating Systems based on UNIX (POSIX) и X / O p e n ' s Common Applications Environment (CAE). Как видно из названия первого стандарта, он базируется на UNIX. Использование этих стандартов позволяет применять один и тот же исходный код д л я р а з л и ч н ы х ОС. Современные операционные системы, к а к правило, удовлетворяют этим стандартам. API современных ОС включает в себя большое число функций. Описание функций WIN A P I для множества ОС WINDOWS приведено, например, в MSDN. Прекрасным учебником по WIN API является [3].
1.3. Функции типичных операционных систем Подведем итоги обзора основных функций ОС. Основными функциями ОС являются следующие: • прием команд или заданий на специальном я з ы к е сценариев и их исполнение; • выделение памяти и загрузка программ, подлежащих исполнению; • выделение времени процессора для запущенной программы; • распределение памяти между компонентами ОС и пользовательскими приложениями и защита их от взаимного в л и я н и я ; 21
• распределение внешних устройств между компонентами ОС и пользовательскими приложениями; • управление всеми физическими устройствами с целью обеспечения максимальной производительности вычислительной системы и (или) пользователя; • планирование и диспетчеризация задач с учетом заданной дисциплины обслуживания; • управление процессами и потоками в режиме квантования времени; • поддержка работы с локальной, корпоративной сетями и глобальной сетью INTERNET; • защита данных от несанкционированного использования; • поддержка 64-битных процессоров. Ниже представлена таблица с функциями основных модулей ОС. Таблица
1.1
Функции о п е р а ц и о н н ы х систем
Функции 3 1. Так как монитор включал трансляцию и компоновку, сами трансляторы И компоновщики часть ОС. 2. Так кик монитор и исполняемая программа одновременно в памяти — зашита программ от взаимного влияния (защите памяти). Управление выполнением пользовательских программ 2 Менеджер ввода-выво- 3. Опрос обработка прерываний. да (много» рогрнммный 4. Стандартизация заиросон(функция, режим 1 откуда, куда). б. Очередь запросов к устройству. Гвяль с внешними устройствами напрямую, т.е. выполнение низкоуровневой работы с устройством. Драйверы устройств стандартные пакеты. 6. Регистрации пользователей и их аутен3 Менеджер процессов тификация для проверки их пряв (login, и потоков. Менеджер password), group. 7. Защита от ошибок п пользовательской программе, из-за которой заблокирована работа других. 8. Защита от злонамеренных действий других пользователей. Название модуля 1 2 Пакетный монитор — исполнительный блок
№
Продолжение 1
2
табл.
1.1
3 9. Учет и ограничение ресурсов для одного пользователя. 10. Квантование времени. 11. Диспетчеризация. 12. Распределение ресурсов (внешних устройств). 13. Управление процессами одного приложения. 14. Дерево процессов (UNIX), Job — WINDOWS. 15. Управление потоками.
4 Сетевой менеджер
16. Открытые сети — 7-уровневая модель взаимодействия, протоколы TCP/IP. 17. Защита пакетов от потерь. 18. Защита пакетов от несанкционированного доступа.
5 Файловые системы
19. Иерархическая файловая система. 20. Оптимизация хранения в системе. 21. Оптимизация поиска в системе. 22. Целостность и восстанавливаемость после сбоев. 23. Журналы регистрации событий. 24. Защищенность, т.е. разделение прав доступа к файлам и папкам. 25. Виртуальная память — отображение внешней памяти на физическую.
6 Базы данных и базы знаний
26. Управление запросами. 27. Стандартизация запросов. 28. Быстрый поиск. 29. Обеспечение целостности и восстанавливаемости.
7 Системы реального времени
30. Управление временем выполнения функций.
8 Многопроцессорные системы
31. Максимальная загрузка процессоров. 32. Синхронизация.
9 Многоплатформенная поддержка
33. Выделение платформенно зависимого кода в отдельную библиотеку.
Ниже будут рассмотрены вопросы построения ОС и использования их функций в п р и л о ж е н и я х пользователя. 23
1.4. Влияние п р о г р а м м н о г о о б е с п е ч е н и я с открытым к о д о м и интернет на проектирование ОС Выше приведены основные функции ОС. Только перечень этих функций показывает сложность и многоплановость задачи проектирования ОС. Первые ОС разрабатывались как архитектурно зависимые ОС и поставлялись пользователю в виде двоичного кода. Это приводило к тому, что к моменту поставки ОС само оборудование уже устаревало, и приходилось вновь разрабатывать ОС с нуля для нового поколения аппаратуры. Для решения втой проблемы использовались следующие методы: — в ОС выделены аппаратно зависимые и оппардтно независимые части. Для создания аппаратно независимых частей использозался язык высокого уровня Си. Как показала практика разработки ОС, аппаратно зависимыми являются приблизительно 10% кода. Пернвя ОС, построенная по этому принципу, — ОС UNIX: — для создания некоторых ОС использовались многочисленные группы программистов, для координации действий которых применялся интернет. Это потребовало распространения ОС в открытых кодах. Из наиболее распространенных ОС по такому принципу погтроена операционная система LINUX. Привлечение к проектированию ОС большой группы заинтересованных разработчиков и квалифицированных пользователей и возможность координации их работы с помощью интернета способствовали ускорению разработки и тестирования компонентов ОС. Распространение ОС в исходных кодах и гибкая настройка ядра и утилит ОС LINUX сделали эту ОС очень распространенной среди квалифицированных пользователей. Возможность получения надежной ОС бесплатно делает эту систему привлекательной для большой группы пользователей. В настоящее время теоретические и практические зопро сы создания ОС широко обсуждаются в интернете. Рекомендуем читателям регулярно посещать не только сайты ведущих разработчиков ОС, таких как IBM, Microsoft, Hewlett-Packard, Apple Computer, а также сайты с научными, учебными и практическими материалами, например, citforum.ru, Iowlevel.ru, xaker.ru, a8m.shadrinek.net и др.
24
1.5. М е х а н и з м ы п о д д е р ж к и м о д е л и «Клиент — с е р в е р » , м о б и л ь н ы х у с т р о й с т в Как покаэал обзор этапов разработки ОС, первые ОС разрабатывались для больших вычислительных систем. Эти системы были очень дороги, и купить их могли только предприятия, способные обеспечить их полную загрузку. В связи с возможностью дистанционной передачи задания и многопользовательского режима появились терминалы для взода и вывода информации. Эти терминалы, становясь все более интеллектуальными, превратились в персональные компьютеры. Терминал «предполагает», что каждый символ, вводимый пользователем, передается на компьютер, который в этом случае называют сервер. Обработкой вводимых данных занимается исключительно сервер. ПК может обеспечить не только Ввод-вывод данных, но и их частичную обработку. Так может быть проверена правильность ввода данных, что исключит передачу неверных данных. Может быть выполнена более сложная обработка. В этом случае говорит о модели «клиент сервер*, которая объединяет в себе возможность совместного использования дорогостоящих компонентов вычислительной системы, расположенных на сервере, и обеспечение минимального трофика, так как по сети передается только необходимая информация. Первой предложила эту модель фирма IBM. основной производитель мейпфреймов. наиболее пострадавшая от широкого внедрения ПК. Она предложила концепцию Connectivity, которая определяет принцип соединения между центральным компьютером (сервером) и ПК (клиентом). Именно эта технология используется для решения высокоприоритетных (высокопроизводительных) задач. Популярность этой модели связана с тем, что овя в полной мере использует возможности клиента и сервера и обеспечивает минимальный трафик между ними, так иак быстродействие передачи данных по сети является наиболее «узким местом» зо всей вычислительной системе в целом. Если нсоользовать ПК как обычный терминал (как в UNIX серверах), посети передаются все входные символы, что существенно уменьшает скорость передачи дониых. Увеличение времени передачи повышает вероятность ошибки ввода, связанной с психологическим состоянием человека, вводящего данные. В клиентсерверной технологии запрос передается на сервер только после сковчания его ввода (т.е. можно исправить все необходимое) и анализа его правильности клиентским приложением- ОС хранит 25
результаты выполнения предыдущих запросов на локальном компьютере, поэтому при поступлении аналогичного запросе ов вообще не передается серверу (хост-машине). Технология »ктиент — сервер» будет рассмотрена в специальном курсе, В данном учебнике она не рассматривается.
1.6. Свойства о п е р а ц и о н н ы х систем Ниже приведены свойства ОС, которые позволяют сравнивать ОС друг с другом. 1.6.1. Эффективность При распределении ресурсов система должна быть в достаточной степени эффективна. Она не должна сама потреблять слишком много ресурсов и предъявлять больших требований к оборудованию. 1.6.2. Надежность и устойчивость Она должна быть такой же надежной, как аппаратура. Быть в состоянии производить определение и диагностику ошибок, а также восстановление после характерных ошибок, произошедших по вине пользователей. Она должна защищать пользователя от его же ошибок или хотя бы минимизировать вред, который они наносят. Устойчивость — возможность восстановления системы после сбоя, например, послегбоя питания. 1.6.3. Гибкость и расширяемость Гибкость — система должна настраиваться в зависимости от поведения пользователя. Ресурсы должпы увеличиваться или уменьшаться в зависимости от задания пользователя. В процессе эволюции добавляются новые средства, ОС должна быть расширяемой для обеспечения эффективного использования быстро изменяемого аппаратного обеспечения. 1.6.4. Переносимость Переносимость — возможность функционирования ОС для рааличпых архитектур процессоров и внешних устройств.
1.6.5. Безопасность
ОС должна защищать п р и л о ж е н и я от взаимного в л и я н и я . Должна минимизировать возможность преднамеренной или случайной порчи данных и программ д л я всех приложений пользователя и самой ОС. Должна з а щ и т и т ь критические ресурсы от несанкционированного доступа. Необходимыми условиями защищенной ОС являются: • возможность определения владельца для каждого ресурса 1 ; • возможность определения для владельца прав доступа. 1.6.6. Совместимость
Возможность использовать ОС д л я процессоров с р а з н о й архитектурой. Совместимость может быть обеспечена на уровне исходных кодов и двоичных кодов. Совместимость на уровне исходных кодов обеспечена для той части ОС, которая написана на языке Си. 1.6.7. Удобство и ясность
Так как ОС предназначена, прежде всего, д л я работы с пользователем, она должна быть спроектирована с учетом человеческого фактора.
1.7. Классификация ОС В зависимости от количества одновременно р е ш а е м ы х задач ОС делится на однозадачную и многозадачную операционную системы. По количеству пользователей, одновременно обслуживаемых ОС, они делятся на однопользовательские и многопользовательские. Основной отличительной чертой последних является о
необходимость аутентификации пользователя при регистрации в системе с целью определения прав пользователя. 1
К ресурсам относятся, например, файлы, устройства, области памяти Аутентификация — процедура, с помощью которой ОС гарантированно определяет пользователя, подключающегося к системе. Простейшим средством для аутентификации является задание имени пользователя и пароля. Более подробно алгоритмы и протоколы аутентификации будут рассматриваться в курсе «Защита информации». 2
27
В зависимости от режима выполнения задач ОС делятся на системы с невытесняемой и вытесняемой многозадачностью. В первых системах передача управления другой задаче выпол няется, если первая задача не может продолжить выполнение в связи с обращением к внешнему устройству, например. Вытесняющая многозадачность означает передачу управления другой задаче не только в случае необходимости выполнения запроса. Выполнение задачи прерывается по истечении заданного кванта времени. ОС с вытесняемой многозадачностью еще называют ОС разделения времени. В качестве объекта для выделения кванта времени могут использоваться процессы или его части; (потоки). ОС, которая поддерживает возможность параллельного выполнения потоков, называется многопоточной. ОС с жесткими требованиями по времени выполнения их функций и приложений, называются системами реального времени. Современные вычислительные системы могут включать в себя более одного процессора. Операционная система, которая поддерживает работу в многопроцессорном режиме, называется многопроцессорной. В связи с большим многообразием процессоров актуальной является задача поддержки нескольких типов процессоров одной операционной системой. В настоящее время разработана теории построения ОС для нескольких платформ. В основе этой теории лежит деление модулей ОС на аппаратно зависимые и аппарат но независимые модули. Для связи между модулями этих групп используется стандартный интерфейс, поэтому для обеспечения поддержки нозого типа аппаратуры необходимо только разработать аппаратно зависимые модули для этой аппаратуры. ОС, предназначенные для работы с различными типами процессоров, называются мвогоплатформенными. Примеры. ОС LINUX является многозадачной ОС с вытесняющей многозадачностью. Она является многопоточной, поддерживает многопроцессорную работу с 32-битными и 64-битлыми процессорами. Это многоплатформенная ОС (поддерживает Hewlett-Packard's Alpha, Itanium, MIPS, SPARC. Motorola MC680x0. PowerPC, серию IBM), обеспечивает возможность работы в режиме реального времени. WINDOWS 2000 является многозадачной ОС с вытесняющей многозадачностью. Она яаляется многопоточной, поддерживает многопроцессорную работу с 32-битными и 64битными процессорами. Это многоплатформенная операционная 28
система. Для определения процессоров, к о т о р ы е п о д д е р ж и в а ются, можно использовать ф у н к ц и ю S e t S y s t e m l n f o . Среди э т и х процессоров 64-битные процессоры ф и р м ы INTEL и AMD. Р е ж и м реального времени не поддерживает.
1.8. Вопросы и задачи 1. Назовите функции пакетного монитора. 2. Какие функции ОС, которые можно использовать в командной строке, вы знаете? Попробуйте реализовать отдельную функцию, например, функцию CD (изменить текущий каталог), в которой задается новый каталог. Сможете ли вы реализовать простейший пакетный монитор, способный выполнить любое число команд CD? Если нет, вспомните об этом задании, когда изучите тему, связанную с Управлением процессами. 3. Какие функции языка высокого уровня позволяют использовать клавиатуру как терминал для посимвольной и построчной передачи набираемых данных? Приведите примеры целесообразного использования обоих режимов работы клавиатуры. 4. Проверьте свойство вытесняемой многозадачности для ОС, с которой вы работаете. Для этого запустите два приложения. Пусть одно приложение выводит строку Applicationl, а второе — Application^ с заданной задержкой 1 многократно. В каком случае можно говорить о том, что ОС вытесняет задачи? 5. Исследуйте возможность использования многопользовательского режима. Изучите группы пользователей. Средствами своей операционной системы добавьте нового пользователя в одну из групп, если ОС это позволяет. Изучите средства управления правами доступа для вашей операционной системы. 6. Найдите сведения о системе и определите типы используемых процессоров для вашей операционной системы 2 . 7. Не запуская ни одного пользовательского приложения, определите модули, загруженные ОС3. Вы увидите огромное число DLL, которые загружает ОС для обслуживания своих и пользовательских приложений. Это является еще одним подтверждением сложности программного комплекса, к изучению которого мы приступаем. 1 Задержку можно задать циклом, например, for (I = О; I < N; I++); значение N следует подобрать в зависимости от производительности процессора так, чтобы примерно после 5 строк для одного приложения получали строки для другого приложения. 2 В среде WINDOWS 2000 для получения этой информации необходимо выбрать Настройка\ Панель управлениях Администрировавие\ Управление компьютером\ Служебные программьД Сведения о системе\ Сведения о системе 8 В среде WINDOWS 2000 для получения этой информации необходимо выбрать Настройка\ Павель управлениях Администрирование\ Управление компьютеромХ Служебные программьД Сведения о системе\ Программная среда\ Загруженные модули
29
2. ОСНОВНЫЕ ПРИНЦИПЫ ОПЕРАЦИОННЫХ
РАЗРАБОТКИ
СИСТЕМ
Цели изучения раздело: 1. Объяснить понятие готического уровня. 2. Объяснить преимущество организации системы в виде иерархии уровней обстракций. 3. Объяснить необходимость API и промежуточного программного обеспечения [middleware]. 4. Объяснить, кок системные ресурсы используются пользовательским и управляются системным программным обеспечением 5. Сопоставить пользовательский режим и режим ядра ОС 6- Объяснить преимущества и недостатки использования прерыва7. Сравнить различные способы декомпозиции ОС: объектно-ориен тированный, модульный, микроядерный, многоуровневый 8. Объяснить применение списко устройств и очереди драйверов I / 0 .
2.1. Методы структуризации 2.1.1- И е р а р х и ч е с к и й м е т о д П р е д л о ж е н Д е й к с т р о й [ 4 ) . О С р а с с м а т р и в а е т с я кпк м н о г о слойная система, состоящая из виртуальных машин- Каждый уровень определяется выполняемыми ф у н к ц и я м и , исходными д а н н ы м и и р е з у л ь т а т а м и в ы п о л н е н и я э т и х ф у н к ц и й . Самый н и ж н и й уровень соответствует аппаратуре. К а ж д ы й очередной у р о в е н ь д л я в ы п о л н е н и я с в о и х ф у н к ц и й м о ж е т п е р е д а в а т ь зап р о с ы в и р т у а л ь н о й м а ш и н е б о л е е н и з к о г о у р о в н я . П о с л е выполнения ф у н к ц и и результат передается абстрактной м а ш и п е более
высокого уровня. Пользователь ОС может игнорировать все виртуальные машины, которые расположены не на самом верхнем уровне. Виртуальная машина i-oro уровня работает только со смежными виртуальными машинами, т.е. с i + 1 и i — 1. Достоинством этого метода является независимость реализаций для к а ж дого уровня, при этом изменение реализации на любом уровне не потребует изменения на остальных уровнях, если интерфейсы и каналы связи между уровнями не нарушены. Если четко определены функции каждого уровня и интерфейс передачи д а н н ы х между уровнями, очень упрощается реализация каждого уровня и ее тестирование. Эта методика используется, прежде всего, при разработке драйверов. При разработке драйверов для логических устройств не учитываются детали работы с конкретными устройствами, так как они лежат на вышестоящем уровне по сравнению с драйверами физических устройств, подключение новых устройств или изменение функционирования устройств не отражается на логическом вводе-выводе и, тем более, на реализации функций ввода-вывода для языков высокого уровня. Пример компонентов ОС на р а з н ы х у р о в н я х а б с т р а к ц и и приведен на рис. 2.1. Каждый слой должен быть независимым от предыдущего. Эта независимость обеспечена с помощью интерфейса взаимодействия между слоями. Единственным способом обратиться к аппаратной части для п р и л о ж е н и я д о л ж н ы быть системные вызовы, и ничего кроме системных вызовов. Например, для того, чтобы выделить память, приложение (разумеется, опять через интерфейс системных вызовов) должно обратиться к менеджеру памяти. Менеджер памяти не имеет прямого доступа к физической памяти и переправляет запрос далее по цепочке аппаратно независимым модулям ядра (естественно, обработав его в соответствии со своими алгоритмами, например, отказав в доступе, если размер свободной п а м я т и м е н ь ш е требуемой). Слой аппаратно зависимых модулей д о л ж е н полностью экранировать особенности а п п а р а т у р ы от о с т а л ь н о й ч а с т и я д р а . В этом случае одни и те же аппаратно независимые модули ядра могут без изменений использоваться на компьютерах с разными процессорами. С другой стороны, системные вызовы не зависят от ОС, так функция CreateFile с точки зрения пользователя одинакова для ОС WINDOWS 95, ОС WINDOWS 98, ОС WINDOWS 2000, ОС WINDOWS ХР, хотя это разные ОС, которые имеют разные ядра. 31
Аппаратура ••
Уровень ядра -
11 • с
Алпаратно-зависимые модули Алпаратн-независимые модули Системные вызовы • --лги"
- - - Уровень пользователи = = = = = Пользовательские приложения
Рис. 2.1. Уровни абстракции для компонентов ОС Таким образом, использование многоуровневой ОС и обеспечение стандартных интерфейсов между этими уровнями обеспечивает возможность модификации каждого из уровней без необходимости изменения других уровней, т.е. независимость всех уровней иерархии. В качестве примера рассмотрим уровни иерархии, используемые при выполнении запроса пользовательской программы на доступ к файлу (функция CreateFile для ОС класса WINDOWS). 1. Слой 1 ОС. Реализован в Kernel32.dll подсистемы Win32. Проверяется правильность переденных параметров. Если в параметрах ошибка возврат ошибки. Если требуется, то формируется полное имя файла с учетом текущего каталога приложения. 2. Слой 2 ОС. Реализован в ntdll.dll. Функция NTCreatefile. Выполняет переключение режима работы с пользовательского в режим ядра. Параметры переписываются в стек режима ядра. В области памяти ядра проверяется наличие объекта «Файл» с таким же именем. Если такой объект есть, то проверяется возможность совместного использования. В случае запрета на совместное использование возврещастся ошибка. Создается новый объект для данного файла. Если память не может быть выделена — ошибка. 3- Слой 3 ОС. Реализован в ntoskmH.exe. Функция NTCreatefile. Работает в режиме ядра. Вызывает функции I/O-Manager. l/O-Manager определяет по имени файла и таблице устройств драйвер, который должен выполнить запрос на работу с файлом. Если задано ошибочное устройство, функция возвращает ошибку. Если запрошенное устройство существует, то создает объект «Драйвер». Драйверу передается запрос на проверку прав доступа. Система безопасности проверяет корректность режимов обращения
к данному файлу. Если запрошенный р е ж и м не поддерживается соответствующей файловой системой или не соответствует правам доступа, возвращается ошибка, перед выходом созданные объекты уничтожаются, память, выделенная для них, освобождается. Например, для файла задано значение в структуре SECURITY, а используется файловая система, не допускающая использования этих данных 1 . Проверяется соответствие требований доступа в запросе и информации о файле в файловой системе. Если установлено несоответствие требований — это ошибка. Если все в порядке, информация о файле (атрибуты, размер, физический адрес, права доступа и т.д.) записывается в объект «Файл» и передается назад. В случае ошибки формируется ошибочный код возврата. Использование этих слоев позволяет обеспечить независимость каждого слоя от всех других слоев. Обращение к устройствам с точки зрения пользователя одинаково для гибких, жестких дисков, CD и USB-устройств. Заметим, что иерархия уровней абстракции используется не только при построении ОС. Наиболее характерным примером такой иерархии является семиуровневая модель открытых систем, которая позволяет изменять к а ж д ы й уровень в отдельности независимо от других уровней. Недостаток иерархической системы. Так как ОС очень сложна, выделение уровней — задача очень сложная. Фактически система представляет собой не последовательную цепочку уровней, а дерево, у которого на к а ж д о м уровне много узлов. Функций очень много. К а ж д а я со своим интерфейсом, интерфейс каждого уровня недостаточно документирован. Разработчики ОС часто нарушают правила, переходя через уровни с нарушением правил взаимодействия. Такую систему очень трудно модифицировать.
2.2. Методология ядра Методология, основанная на ядре, состоит в том, что из всех модулей выбираются те, которые я в л я ю т с я у н и в е р с а л ь н ы м и для всех ОС. В этом случае расширение и изменение служб ОС, как правило, не влечет за собой изменения ядра. Этот принцип 1 Параметры безопасности допустимо задавать для файловой системы NTFS и не допустимо для FAT12.
33
положен в основу разработки ОС U N I X и последних версий WINDOWS. Кроме этого, некоторые модули ОС требуются всем приложениям, независимо от их типа. Другие модули используются только некоторыми приложениями. Например, модуль управления памятью используется приложениями любого типа, управление локальной сетью не является модулем, необходимым для любого приложения. Модули операционной системы, соответственно, делятся на 2 класса: • ядро ОС модули, необходимые для работы любого приложения. эти модули постоянно находятся в памяти; • утилиты - модули ОС, которые загружаются в память по мере необходимости и выгружаются из памяти после использования. Основной критерий разделения — это уровни привилегий кода. Современные процессоры поддерживают разное число уровней привилегий. Например, процессоры типа 1-32 используют 4 уровня привилегий. Другие процессоры — только два- Для обеспечения совместимости большинство ОС используют 2 уровня привилегий, независимо от архитектуры процессора: уровевь пользователя и уровень супервизора- По тому, какие части ядра на каком уровне привилегий работают, все архитектуры подразделяются ва три типа: архитектура с монолитным ядром, микроядерная и эквоядерная. 2-2.1- Монолитное ядро В системах с монолитной архитектурой все ядро работает на уровне супервизора. Именно ядро такой архитектуры приведено на рис. 2-1 Достоинства такой системы: — простота разработки, так как не н у ж н о разрабатывать приложения для резных уровней; — высокая скорость работы за счет отсутствия необходимости переключения между уровнями для взаимодействия модулей ОС между собой, а такие взаимодействия выполняются достаточно часто из-за многослойной ярхитектуры ОС. Недостатки: — большой объем оперативной памяти занят ядром ОС, следовательно, для программ пользователя остается меньший объем памяти; поэтому для таких ОС предъявляются высокие требования к ресурсам компьютера; 34
— так как все модули работают в одном адресном пространстве, то сбой одного модуля ОС может привести к сбою всей системы. Ошибка в ядре ОС очень опасна. Непосредственное взаимодействие между объектами ядра может привести к к р а х у системы в целом из-за наличия ошибок в отдельных модулях. Примеры ОС с м о н о л и т н ы м я д р о м : т р а д и ц и о н н ы е я д р а UNIX, такие как BSD, LINUX. 2.2.2. Микроядро
В системах с микроядерной архитектурой на уровне супервизора работает только очень небольшая часть ОС, которой требуется непосредственный доступ к аппаратуре. Остальные модули ОС работают в пользовательском режиме. Эти модули называются службами (сервисами). Примером микроядерной ОС является система Mach, разработанная в университете Карнеги — Медлона. Что же представляет собой микроядро? Аналогом микроядра является набор функций базового класса общего вида при объектно-ориентированном программировании. Оно состоит из небольшого (как правило) набора абстракций, которые не составляют ОС сами по себе, но позволяют реализовать ОС в виде служб, которые будут использовать предоставляемые микроядром сервисы. Например, микроядро Mach предоставляет следующие абстракции: задачи, потоки, объекты памяти, порты и сообщения. Этого достаточно, чтобы построить на их базе полноценную операционную систему лишь с помощью тех частей, которые будут работать в пользовательском режиме. Функции ядра обычно не зависят от конкретной ОС. Микроядро можно рассматривать к а к набор необходимых служб и использовать их в любой ОС, к а к вновь разрабатываемой, так и существующей. Так, эти службы использовались в ОС с монолитным ядром; к примеру, Apple отобразила LINUX на микроядро Mach для использования на PowerMac. Название «микроядро» подразумевает м а л ы й размер ядра, так как оно предоставляет гораздо меньше сервисов, чем в случае смонолитным ядром. Так, есть системы, в которых микроядро занимает всего 32 Кбайта. Разница между пользовательскими п р и л о ж е н и я м и и компонентами ОС, работающими в пользовательском режиме, чисто условна. Принято считать, что сервер ОС отличается от приложе35
ЕИЯ тем, что он предоставляет какие-либо услуги приложениям. Именно в этом смысле здесь используется термин «сервис*. Рассмотрим достоинства и недостатки микроядерной ОС. Достоинство микроедерных ОС
Чрезвычайно высокая степень модульности и расширяемости. Использование ядра, которое ве зависит от конкретной операционной системы, является, безусловно, преимуществом по сравнению с использонвныем монолитного ядра. Любые возможности операционной системы определяются лишь приложением пользовательского режима. Соответственно, простым запуском и остановкой таких приложений можно совершенно изменить систему. Стабильность и безопасность. Эти два свойства системы зависят только от мпкроядра. В связи с небольшим размером кода для мпкроядра этот код можно тщательно отладить, выполнить его верификацию формальными, математическими методами. Остальные компоненты не являются критическими, и их можно легко перезапустить в случае сбоя. Так как в адресном пространстве ядра работает лишь небольшое число модулей, сбои в этих модулях не являются критичными, они не влинют на работу других модулей, работающих в пользовательском режиме. Простота программирования модулей пользовательского режима. Обычно программирование пользовательских приложений и компонентов ОС существенно отличается. Так, драйверы для DOS и различных версий WINDOWS имеют разные структуры. и для их отладки используются различные программные среды. Внутри драйверов используются функции выделения памяти, ввода-вывода и т.д., отличные от функций для этих же целей в пользовательском режиме. В случае же микроядра и драйвер, и обычное приложение пользователя используют одни и те же программные средства. Недостаток м и к р о я д е р н о й с т р у к т у р ы я д р а
Недостаток использования микроядра понижение быстродействия. Это связано с тем, что взаимодействие между отдельными компонентами ОС и ядром, а также компонентами, работающими в пользовательском режиме, возможно только через ядро ОС. Так, те данвые, которые в монолитной системе компонент ядра мог просто прочитать пз системной области памяти, сервер микролдерной системы вынужден получить, используя механизмы межпроцессного взаимодействия (IPC — InterProcess
Communication). Таким образом, для обеспечения взаимодействия необходимо несколько раз переключаться м е ж д у пользовательским и режимом ядра. Переключения между этими уровнями привилегии занимают много процессорного времени. 2.2.3. Экзоядерная система
Микроядро в своем идеальном проявлении состоит только из средств IPC (взаимодействие пользовательских приложений с модулями ОС и модулей ОС между собой осуществляется при помощи тех же средств). Рассмотрим применение концепции микроядра на примере микроядра операционной системы Tyros [11]. За основу IPC были выбраны очереди сообщений. При необходимости взаимодействия посылается запрос в виде сообщения. Сообщение помещается в очередь сообщений. Если очередь сообщений заполнена полностью, то процесс, который послал сообщение, останавливается до тех пор, пока очередь освободится и станет возможным передача сообщения. Ядро включает в себя следующие функции: send — послать сообщение, recv — получить сообщение и wait — ж д а т ь сообщение. Вызов recv является асинхронным, т.е. сразу после запуска примитива recv выполняется очередной оператор программы. Для синхронной отправки сообщения следует последовательно вызвать recv и wait. Как получателем, так и отправителем сообщения может являться объект, которому выделяется процессорное время. Для современных ОС это потоки, процессы или то и другое. Если в микроядре, кроме IPC, должны быть средства выделения ресурсов, например, памяти, то в случае квазиядра эти возможности предоставляются через IPC. Каждый сервер получает в свое распоряжение л и ш ь те системные ресурсы, на которые он имеет право. Д л я обеспечения безопасности в сообщении задается уровень привилегий объекта, пославшего это сообщение (модуль ОС или модуль пользователя). Объекты пользователя имеют доступ только к IPC, а объекты ОС также имеют возможность просить у ядра различные ресурсы. Этот простой механизм защиты, подобный тем, что присутствуют в современных процессорах, позволяет серверам микроядра создавать любые и сколь угодно сложные системы з а щ и т ы . Это основное достоинство данного типа ядра. В настоящий момент такие системы активно исследуются, но полноценно работающих ОС на этом принципе пока не существует. 37
Это связвно с тем, что они требуют выделения всех ресурсов модулями. работающими в пользовательском режиме. Заметим, что в DOS существовала бесконтрольная возможность доступа к устройствам в пользовательском режиме, в котором работали модули ОС и пользовательские модули. Для обеспечения защиты в современных процессорах и ОС можно включить возможность управления внешними устройствами только в режиме ядра. Например, для процессора 1-32, минимальный уровень приоритета программы, которая способна управлять внешними устройствами, определяется содержимым 12, 13 битов регистра флагов (это поле называется IOPL, Input-Output Privilege Level). Фрагмент программы для определения этого уровня приведен ниже: unsigned
uLevel; „ asm
i pustifd pop shr end mov
eax eax. 12 вах, 3 [uLevel], eax
) pnntf ("uLevel = %d\n",
uLevel);
Ответ 0 соответствует уровню привилегии 0, т.е. возможности управления внешними устройствами только модулями, которые работают на О уровне привилегии, что соответствует уровню ядра. Попытка изменения этого уровня в польвоввтельской программе с помощью команд и последующая проверка нового значения показывают, что оно не изменяется, хотя код, приведенный ниже, выполняется без ошибок. Изменить это поле может программа, уровень привилегии которой не хуже, чем тот, что задан в поле IOPL. asm
( pushfd pop or push popfd
вах eax. 3 SHL 12 eax
38
pushfd pop shr and mov
eax eax, 12 eax, 3 [uLevel], eax
}
printf ("uLevel = %d\n", uLevel);
Если режим ядра будет использоваться для обеспечения проверки возможности доступа к внешнему устройству и параметров доступа, то без ограничения защищенности м о ж н о позволить выполнение самого доступа в пользовательском режиме. Именно этот принцип используется в экзоядерных системах. 2.2.4. Ядра для современных ОС
Для большинства современных ОС в состав ядра, к а к правило, входят следующие модули: — модули управления вводом-выводом — эти модули используются, прежде всего, при загрузке самой ОС. В этом случае сначала загружается программа начальной загрузки под управлением базисной системы ввода-вывода (Basic Input-Output System — BIOS). Эта программа запускается и загружает первую порцию модулей ОС. Остальные модули ОС загружаются модулями ОС, загруженными на предыдущем шаге. Д л я DOS загрузка выполняется в 2 этапа. Для современных ОС загрузка выполняется в 4 и более этапов. На каждом этапе возможности ОС с точки зрения управления вводом-выводом все время расширяются. Наиболее распространенными з а г р у з ч и к а м и я в л я ю т с я , например: NTLDR (NT — LoaDeR) — з а г р у з ч и к я д р а д л я с о в р е м е н н ы х WINDOWS; LILO (Linux LOader) — загрузчик ядра LINUX; — модуль управления памятью. Д л я загружаемых модулей ОС необходимо выделить память, куда будет загружен код и данные для модуля. При запуске и выполнении любого приложения ему должна быть выделена память, поэтому модуль управления памятью обычно постоянно присутствует в памяти. Если оперативной памяти для загружаемого модуля не хватает, дополнительная память должна быть получена за счет освобождения ее путем сброса неиспользуемых в настоящее время данных и программ в специальный файл подкачки. Если программа и данные, которые сейчас должны выполняться, находятся в страничном файле, они должны быть загружены в оперативную память; 39
— м о д у л ь у п р а в л е н и я п р о ц е с с а м и . В ы п о л н е н и е м любого п р и л о ж е н и я у п р а в л я е т ОС. Она з а г р у ж а е т п р и л о ж е н и е в память 1 , з а п у с к а е т его, в ы д е л я е т д л я него п а м я т ь и в р е м я процессора, завершает его. Ф а к т и ч е с к и всегда в ы п о л н я е т с я не менее 2 процессов — один и л и более процессов ОС и пользовательские процессы. Д л я у п р а в л е н и я э т и м и процессами с целью обеспечения м а к с и м а л ь н о й производительности, возможности их согласован и я и и с к л ю ч е н и я нежелательного в л и я н и я используется модуль у п р а в л е н и я процессами; — м о д у л ь д л я м е ж п р о ц е с с н ы х с о е д и н е н и й I P C . Важность этого м о д у л я рассмотрена в ы ш е . 2 . 2 . 5 . Примеры ядер для ОС Ядро для W I N D O W S 2 0 0 0
К м о д у л я м я д р а относятся следующие: — и с п о л н и т е л ь н а я с и с т е м а ( N t o s k r n l . e x e ) , к о т о р а я включает в себя у п р а в л е н и е п а м я т ь ю , у п р а в л е н и е вводом-выводом, управление процессами и п о т о к а м и , у п р а в л е н и е безопасностью и межпроцессные соединения; — д р а й в е р ы ( п р о г р а м м ы с р а с ш и р е н и е м s y s ) (драйверы устройств, драйверы ф а й л о в ы х систем, д р а й в е р ы д л я управления сетью); — аппаратно-зависимый уровень (hardware abstraction layer —HAL.dll); — модули подсистемы Win32 (Kernel32.dll, Advapi32.dll); — ф у н к ц и и графического и оконного интерфейса (User32.dll, Gdi32.dll). П е р е ч е н ь к о м п о н е н т о в я д р а W I N D O W S 2 0 0 0 показывает, что оно не я в л я е т с я м и к р о я д р о м в полном смысле слова. В привилегированном р е ж и м е в ы п о л н я ю т с я не т о л ь к о основные компоненты системы (модули у п р а в л е н и я п а м я т ь ю , вводом-выводом, процессами), но и другие к о м п о н е н т ы , т а к и е к а к ф а й л о в ы е систем ы , системы у п р а в л е н и я сетями и др. Это сделано д л я увеличения производительности системы. Такое я д р о н а з ы в а ю т гибридным. 1 Для современных ОС вместо загрузки приложения в память может использоваться отображение дискового пространства с программой на память.
40
Для реализации всех компонентов используется преимущественно язык Си. Я з ы к ассемблер используется только в том случае, если необходимо р е а л и з о в а т ь код, к о т о р ы й на я з ы к е высокого уровня запрограммировать очень трудно, или код на ассемблере, существенно выигрывающий по производительности. С такими задачами мы встречались в первой части курса. Кроме этого, модуль HAL реализован преимущественно на ассемблере. Все компоненты ядра, а т а к ж е драйверы устройств используют одно и то же адресное пространство ядра. Это означает, что ошибка в модуле ОС или драйвере может разрушить другие компоненты операционной системы и драйверы. Компоненты ОС и особенности построения драйверов будут рассмотрены в данном курсе. Использование объектов при составлении программ позволяет скрыть свойства объекта от внешних программ. Именно это свойство объектов используется при применении объектов ядра в пользовательских программах. Идентификатор объекта известен пользовательской программе. Поэтому она может указать на него. Закрытые свойства этого объекта и ф у н к ц и и для пользовательских приложений остаются з а к р ы т ы м и . К объектам ядра относятся: — объекты управления, например, асинхронные процедурные вызовы (Asynchronous procedure calls — АРС1), ф у н к ц и и отсроченного вызова (Deferred procedure call — DPC2) и некоторые объекты, которые используются системой управления вводом-выводом, такие как объект прерывания ( i n t e r r u p t object); — объекты диспетчеризации, например, объекты синхронизации (событие, мьютекс,...). Аппаратно-зависимые компоненты ОС (Hardware abstraction layer — HAL) позволяют сделать ОС многоплатформенной. Ядро ОС загружает этот модуль для работы в режиме ядра. Из всех модулей этого уровня на этапе инсталляции выбирается модуль, который соответствует процессору. Этот м о д у л ь к о п и р у е т с я 1
Используются, если необходимо в пользовательском режиме или режиме ядра выполнить функцию в адресном пространстве текущего потока. Для каждого потока формируется своя очередь АРС. " Функция которая выполняет системную задачу, но ее приоритет ниже, чем приоритет текущей задачи. В этом случае выполнение данной функции может быть отложено, отсюда название функции - отложенная (deferred). Система формирует общую очередь отложенных функций.
41
в системный каталог WINDOWS под именем Hal.dll. Другие операционные системы, такие как VMS, выбирают требуемую библвотеку DLL на этапе загрузки. 2.2.6. Ядра пля UNIX и LINUX Для большинства версий UNIX и всех версий LINUX используется монолитное ядро. Исключение составляет версия UNIX Carnegie-Mellon'sMach 3.0, для которой используется микроядро, и DragonFly BSD, в которой используется гибридное ядро. Для уменьшения требуемой памяти для ядра некоторые его модули (драйверы устройств) могут загружаться и выгружаться из памяти по мере необходимости. Ядра этих систем максимально минимизированы и не содержат ни одной функции, которая непосредственно служит пользователю. Ядро содержит многочисленные системные таблицы, списки, деревья, в которых находится важная системная информация. Вот почему зти системы называют системами, структура которых определена данными. Работа систем в большинстве случаев сводится к поиску и модификации атих данных, поэтому большое внимание уделяется организации данных; так, если используются таблицы, то это, как правило, хеш-таблицы, если списки — то двухнаправленные связанные списки; если деревья, то сбалансированные деревья [12].
2.3. Абстракции, процессы и ресурсы Для упрощения разработки ОС используется принцип «Разделяй и властвуй». Согласно этому принципу сложные объекты делятся на простые объекты. Деление выполняется до тех пор, пока реализация объекта не становится простой. Наиболее подходящей единицей декомпозиции для ОС являются процессы. Процесс, аналогично объекту в ООП, является носителем данных и выполняет функции. Благодаря драйверам внешних устройств их индивидуальные свойства маскируются, например, для чтения с дискеты, винчестера, флеш-диска используются одни и те же команды. Внешние устройства, процессор, память, в том числе и внешняя, рассматриваются как ресурсы, которыми должна управлять ОС. Единица, претендующая на ограниченное число ресурсов внутри вычислительной системы, называется процессом. Основ42
ным ресурсом является время процессора. Так к а к одновременно в вычислительной системе может быть значительно больше процессов, чем процессоров, они конкурируют за владение процессором. Поэтому проблема управления процессами я в л я е т с я актуальной. Цель управления — уменьшить число простаивающих устройств и увеличить производительность вычислительной системы в целом. Для управления процессами используются системные процессы, которые находятся в п а м я т и одновременно с пользовательскими процессами. Эти процессы могут использовать общие ресурсы, например, библиотеки для графических функций. Так как общие ресурсы находятся в памяти только в одном экземпляре, достигается экономия памяти. Таким образом, в памяти одновременно находятся системные и пользовательские процессы. Б чем их отличие? Системные ресурсы, как правило, управляются системными процессами. Эти процессы не могут конкурировать друг с другом, так к а к управляют ими. Пользовательские процессы посылают запросы системным процессам. Системные процессы могут породить другой процесс, выделив ему необходимые ресурсы. Пользовательские процессы не могут порождать процессы. Системный процесс не может послать запрос на обслуживание системному процессу. Пользовательский процесс не может выполнить непосредственно операцию ввода-вывода, а системный процесс может. Пользовательский процесс может запросить ресурс, для системного процесса либо изначально выделяются необходимые ресурсы, либо он сам управляет этим ресурсом.
2.4. Необходимость API и промежуточного программного обеспечения (middleware) Выше (1.2.10) было определено понятие API. Напоминаем, что API позволяет пользователям и их п р и л о ж е н и я м в полной мере использовать возможности, предоставленные операционной системой. Все средства программных интерфейсов м о ж н о разделить на 2 класса: команды, используемые д л я написания командных файлов, и системные вызовы, которые позволяют приложению использовать ф у н к ц и и ОС, т а к и е к а к ввод-вывод данных, управление распределением п а м я т и и т. д. С этим классом функций мы познакомились в первой части курса. 43
Д л я н е п о с р е д с т в е н н о г о о б р а щ е н и я к д р а й в е р а м используете* с п е ц и а л ь н ы й к л а с с ф у н к ц и й , к о т о р ы й н а з ы в а е т с я DevicelOConlml д л я W I N D O W S и i o c t l д л я О С класса U N I X . Р а с с м о т р и м пример п р о г р а м м ы и с п о л ь з о в а н и я ф у н к ц и и DevicelOControl д л я определения геометрических параметров жесткого диска. tfincludestdafx
h*
int_tmain(int агдс. _TCHAR' argvfl) { DISK_GEOMETRY
DiskGeometry;
HANDLE h~ Create WeflHU\PhystcalDriveO*, 0. FILE_SHARE_READ | FlLE_SHARE_ WRITE. NULL. OPEN_EXlSTING. 0. 0): if(b == INVALID_HANDLE_VALUE) { printf ('Драйвер не доступный In "J; return 1: } DWORD dwCount: boolbDeviceloControl{h. IOCTL_DISK_GET_DRIVE_GEOMETRY NULL. 0, &DiskGeometry. s'aeof(DiskGeometry). &dwCounl, 0); CloseHandle(h); printf ('BytesPerSector = %d\n". DiskGeometry.BytesPerSeclor); printf ('Cylinders = %d\n', DiskGeometryCylmders-QuadPart); printf ('SeclorsPerTrack ~ %d\nm, DiskGecrmlry. SeclorsPerTrvck); printf CTracksPerCybnder- %d\n". DiskGeometry TracksPerCylmder); printf CCommonSae = %dM\n". DiskGeometry BytesPerSector * DiskGeometry.CyHnders.QuadParfDiskGeometry.SectorsPerTreck DiskGeometryTracksPerCylinder/11024 • 1024)); return b; i В э т о й п р о г р а м м е о п р е д е л я е т с я р а з м е р с е к т о р а (BytesPerSectorJ, к о л и ч е с т в о д о р о ж е к ва о д н о й с т о р о н е [Cylinders), количество с е к т о р о в на д о р о ж к е [SeclorsPerTrack) и к о л и ч е с т в о сторон (TrecksPerCylinder). Д л я о п р е д е л е н и я о б щ е г о р а з м е р а д и с к а все п а р а м е т р ы д о л ж н ы б ы т ь п е р е м н о ж е н ы . П а р а м е т р «количество д о р о ж е к на о д н о й стороне» в с т р у к т у р е з а д а е т с я к а к 64-биткое ч и с л о . О б р а т и т е в н и м а н и е н а п а р а м е т р ы ф у н к ц и и CreateFile.
Имя файла — это имя первого винчестера. Второй параметр равен 0, так как для данного устройства операции чтения и записи ие будут выполняться. Остальные параметры понятны из первой части курса. Заметим, что для доступа к устройству с помощью функции CreateFile необходимы права администратора. В противном случае функция CreateFile завершится неблагополучно. В функции DeviceloControl в качестве параметров задаются: h — дескриптор устройства; IOCTLJ)tSK_GET_DRIVE_GEQMETRУ — номер выполняемой функции. Очередные два параметра определяют буфер и его размер для исходных данных для драйвера. Для операции IOCTL_DISK_GET_ DRIVE GEOMETRY исходных данных не требуется, поэтому соответствующие параметры равны О; WiskGeometry. slzeof(DiskGeometry) — определяют буфер и его размер для результатов работы драйвера. В качестве результата получается структура типа DISK_GEOMETRY. Последние два параметра такие же, как для функций ReadFile н WriteFile. Заметим, что номера функций, которые можно использовать в пользовательской программе, определяются в самом драйвере. Это гарантирует защиту от использования опасных функций в приложении пользователя. Middleware - это слой программного обеспечения м е ж д у двумя приложениями, которые созданы с помощью различных платформ. Это программное обеспечение позволяет согласовать дпттые между приложениями, например, связать системы управления базами данных с WEB-сервером 1 . Цель программного обеспечения этого класса не только согласование данных, но и обеспечение безопасного использования ресурсов вычислительной системы и приложения с помощью управления приввлегиями пользователей и приложений. Это программное обеспечение включает в себя такие службы, как идентификация пользователя, его аутентификацию н авторизацию, выполнение политики безопасности. Изучение такого программного обеспечения выходит за рамки данного курса.
1
С* Kww.inlrDrwtjourrfll.com 45
2.5. Потребности приложений и эволюция программного и аппаротного обеспечения С начала эры ЭВМ (1950 г.) прошло много поколений аппаратного и программного обеспечения. Смена поколения аппаратного обеспечения, как правило, с некоторым опозданием, приводила к смене поколения программного. Каждое новое поколение аппаратного обеспечения приводило к новому поколению ОС. Кроме этого, на смену ОС влияло желание добиться большей эффективности, большей защищенности, лучше использовать новые достижения в технологиях программирования, например, ООП Первые вычислительные машины использовались в основном для математических вычислений, особое внимание при этом уделялось быстродействию процессора при выполнении его освовных команд. Первые компиляторы и операционные системы фах тическя наиболее полно обеспечивали эти потребности. Дальнейшее развитие внешних устройств обеспечило возможность использования вычислительной техники для хранения и обработки больших объемов информации, что привело к усовершенствованию модулей управления вводом-выводом ОС. По мере усовершенствования процессоров и увеличения их быстродействия однопользовательские системы не могли полностью загрузить вычислительную систему. Для обеспечения параллельного доступа к этой системе нескольких пользователей совершенствовалась ОС. Увеличение объема кода для самой ОС и различных приложений. а также усовершенствование и увеличение стоимости периферийных устройств сделали актуальным использование локальных сетей для обеспечения возможности применения об щих устройств и программного обеспечения на разных рабочих станциях, что, в свою очередь, породило необходимость создания модулей управления сетями. Использование вычислительных систем для обработки графической и ЗВУКОВОЙ информации расширило состав команд процессора командами ММХ. а также потребовало от операционной системы средств для прямого доступа к устройствам (ActiveX-компокеиты). Большое разнообразие средств разработки программвых модулей п необходимость объединения компонентов, разработанных с помощью рааличных технологий, привели к необходимости создания компонентов, которые поставляются в двоичном виде 4С
{COM. DCOM-технологии) и могут быть использованы в любых приложениях. Всвязкс Быстрой сменой аппаратных средств и усложнением ОС необходимо было усовершенствование технологии создании ОС. Был создан язык высокого уровня для написания большей часта ОС. Компоненты ОС были разделены на аппаратно вависвмые и вппаротно независимые, что дало возможность создавать нпогоплатформевные ОС. ОС разрабатывалась как система с хвогослонной архитектурой, позволяющая вносить изменения в отдельные слои без изменений всех остальных слоев. Были созданы мвкроядерные максимально надежные ОС. Сегодня в саази о переходом с 32-бнтных процессоров на б4-битвые выполняется суевп аппаратных платформ, поэтому создаются ОС для поддержки Взбитых процессоров. В настоящее время вычислительные системы применяются пля решевия вычислительно емких задач, например, для шифрования данных используются простые числа длиной больше 1000бит, п над этими числами производятся достаточно сложные математические операции. Для увеличения мощности вычислительных систем несколько процессоров объединяются в одну систему. Это заставляет ОС решать множество дополнительных проблем, свазадных с максимальной загрузкой системы и обеспечением корректного доступа к общей памяти и другим ресурсам. Интернет позволяет выполнять распределенные вычисления. Управление этими вычислениями, как и самим интернетом, выполняет ОС. Таким обраосм, повышение сложности решаемых задач приводит к повышению требований к аппаратура и программному обеспечению, более совершенная аппаратура вместе с программных обеспечением позволяет решать все новые и новые задачи. Для более аффективного их решения аппаратно поддерживаются многие функции операционных систем. Для поддержки этих фупкций введен специальный режим функционирования процессора — режим ядра.
2.6. Понятие режимов ядра и пользователя. Переключение м е ж д у р е ж и м о м я д р а и пользователя При изучении ядерной структуры ОС уже рассматривались режимы ядра и пользователя (сл. 2.2). Для обеспечения меха47
{COM. DCOM-технологии) и могут быть использованы в любых приложения*. Всвязкс Быстрой сменой аппаратных средсти и усложнением ОС необходимо было усовершенствование технологии создания ОС. Был создан нзык высокого уровня для написания большей часта ОС. Компоненты ОС были разделены на аппаратно вависвмые и вппаротно независимые, что дало возможность создавать ниогоплатформенные ОС. ОС разрабатывалась как система с хпогослойкой архитектурой, позволяющая вносить изменения в отдельные слои без изменений всех остальных слоев. Были созданы мвкроядерные максимально надежные ОС. Сегодня в саази о переходом с 32-бнтных процессоров на б4-битвые выполняется смени аппаратных платформ, поэтому создаются ОС для поддержки 64-битных процессоров. В настоящее время вычислительные системы применяются щи решения вычислительно емких задач, например, для шифрования данных используются простые числа длиной больше 1000бит, п над этими числами производятся достаточно сложные математические операции. Для увеличения мощности вычислительных систем несколько процессоров объединяются в одну систему. Это заставляет ОС решать множество дополнительных проблем, свазадных с максимальной загрузкой системы и обеспечением корректного доступа к общей памяти и другим ресурсам. Интернет позволяет выполнять распределенные вычисления. Управление этими вычислениями, как н самим интернетом, выполняет ОС. Таким обраопм. повышение сложности решаемых задач приводит к повышению требований к аппаратура и программному обеспечению, более совершенная аппаратура вместе с программных обеспечением позволяет решать все новые и новые задачи. Для более аффективного их решения аппаратно поддерживаются многие функции операционных систем. Для поддержки этих фупкций введен специальный режим функционирования процессора — режим ядра.
2.6. Понятие режимов ядра и пользователя. Переключение м е ж д у р е ж и м о м я д р а и пользователя При изучении ядерной структуры ОС уже рассматривались режимы ядра и пользователя (сл. 2.2). Для обеспечения меха47
низма защиты операционной системы от программ пользовател» и увеличении эффективности управления ОС целиком или ее основные модули работают в режиме ядра, в отличие от приложений пользователей и отдельных модулей ОС, которые применят режим пользователя. В ранних операционных системах дапныг режимы реализовывались на уровне ОС. Для современных процессоров аппаратно эти режимы рааличаются, и в системе команд предусмотрены команды для переключения режимов работы. Например, процессоры архитектуры I A - 3 2 поддерживают не a 4 режима, из которых О, 1, 2 считаются привилегированный и могут использоваться для ядра и утилит ОС, а ражим 3 соответствует пользовательскому режиму, который применяется для приложений пользователя. На аппаратном уровне реализованы правила защиты памяти в привилегированных режимах. Ниже будут рассмотрены особенности работы процессора в различных режимах и переключение между этими режимами на примере процессоров типа IA-32. 2.6.1. Особенности функционирования процессора типа IA-32 в реальном режиме Известно, что процессор после включения питания нахо дится в так иазываамом реальном режиме. Для задания адреса в реальном режиме используется 2 компонента: сегмент и смеще ние, каждый компонент размером 16 бит. Сегмент задается в так называемом сегментном регистре, смещение — в регистре общей назначения или константой. Размер компонента определялся, исходя из разрядности регистров процессоров 8086. Для обеспечения созместимости с этими процессорами для реального режима 32-битных процессоров используются компоненты такой же длины. Адрес вычисляется по формуле: сегмент '16 + смещение.
(I)
Так как максимальные значения 16-битных компонентой равны OxFFFF, то максимальный адрес памяти, определенной по формуле (1), равен OxlOFFEF. т.е. немногим более 1 Мбайт (1 Мбайт = 2 г о байт = 0 x 1 0 0 0 0 0 байт). Из этого адресного пространства для программ операционной системы и пользователя используютсч адреса 0. .0x9FFFF. т.е. всего 6 4 0 Кбайт. Адресное пространство OxAOOOO-.OxBFFFF используется для хранения содержимого экрана монитора в текстовом и графическом режимах. 50
т и несколько LDT — по одной для каждого приложения. Каждому сегменту программного модуля соответствует одна строка таблицы дескрипторов. Выбор сегментного регистра определяется типом сегмевп. По умолчанию для сегмента данных используется сегментный регистр DS, для сегмента кода — регистр CS, для стека — регистр SS. Кроме перечисленных выше регистров, можно использовать любой другой сегментный регистр (ES. GS, FS), если он определея при задании адреса. Например, адрес памяти [ES:EAX*4} исподь зует сегментный регистр£S. Для обеспечения обслуживания программных модулей с учетом привилегий для каждого сегмента процессор поддерживал 4 уровня привилегий: 0 соответствует наиболее привилсгировавным сегментам, 3 — наименее привилегированным. Как правило уровень привилегии О назначается модулям ядра операционной системы, уровень привилегии 3 — пользовательским программам, остальные уровни привилегий могут использоваться утилитами операционной системы, драйверами. Селектор (сегментный регистр) включает в себя следующую информацию, начиная с младших бит: • тип используемой таблицы (локальная или глобальная) — 1 бит, 0 для глобальной таблицы : • значение уровня привилегии сегмента (2 бита); • номер строки в соответствующей таблице дескрипторов (13 бит). Два бита, которые применяются для задания уровня привн легии, определяют число возможных уровней 4. Напоминаем, что уровень 0 соответствует режиму ядра, уровень 3 — режиму пользователя. Так как для задания номера строки в таблице НС' пользуется 13 бит, максимальное количество строк в таблице равно 21Я, т.е. 8192 строки. Таким образом, одновременно в памяти могут храниться 8192 сегмента, соответствующих GDT и столько же сегментов, соответствующих LDT. Строка таблицы дескрипторов имеет одинаковую структуру для обеих таблиц. Рассмотрим назначение основных полей. Предел сегмента (определяется как размер сегмента) — 1, т.е. максимальное смещение в сегменте. Для 33-битного процессора предел позволяет задать максимальный размер сегмента равным 2зг, или 4 Гбайт. Таким образом, предел определяв] БО
максимальное значение смещения в команде. Если значение смещения превосходит предел сегмента, то аппаратно формируется ошибка адресации. Заметим, что предел сегмента для стека задастся не так, как для сегмента данных или кода. Допустимыми являются смещения от Предел + 1 до максимально допустимого FFFFFFFF. Таким образом, размер стека максимальный, если значение предела для него равно 0. НАЧАЛЬНЫЙ адрес сегмента (для стека — это адрес после вершины стека, если стек пуст). Для 32-битного процессора этот адрес задается 32-битным числом. Начальный адрес сегмента и его предел задают предельные значения для нижней и верхней 1раш)ц адреса сегмента. Если в команде задан адрес, выходящий за пределы допустимых адресов сегмента как снизу, так и сверху, то еппвратво формируется ошибка адресации. Свойства сегмента. Некоторые из етих свойств являются иостояянымя для данного сегмента, т.е. не изменяются в процессе выполнения соответствующего программного модуля. Другие свойства изменяются. К постоянным свойствам сегмента отвосятся класс сегмента и его уровень привилегии. Класс сегмента задает, что это: сегмент команд, данных или стек. Для сегментов данных и стека в поле этого типа задаются также допустимые операции (чтевие-запнсь). Для сегмевта команд здесь можно установить флаг «Согласованный сегмент* [2.6.3]. Кроме этих сегментов, которые называются обычными, используются специальные сегмевты (системные), например, шлюз. TSS и др. Назначение системных сегментов будет рассмотрено ниже. Уровень привилегии сегмента определяется точно так же, как уровень привилегии в селекторе. К переменным полям относятся флаги: «Наличие доступа к сегменту» н «Наличие сегмента в памяти». Первый флаг устанавливается процессором при наличии доступа к сегменту, который задается данной строкой дескриптора. Модуль управления памятью операционной системы использует этот фляг для определения сегмента, который должен быть вытеснен иа памяти в случае ее нешатки. Вытесняется сегмент, к которому вебыло обращения наиболее долго. Прежде чем читать далее, подумайте, какви образом можно определить сегмент, неиспользуемый наиболее долго, с помощью такого флага? Мы этот алгоритм рассмотрим в разделе, евнаанном с управлением памятью. Другой модуль операционной системы, работающий в фоновом режиме, должен сбрасывать этот флаг. Флаг наличия сегмента в памяти 51
устанавливается после загрузки сегмента в память и сбрасываетм ' после его вытеснения. Таким образом, на аппаратном уровне поддерживается защити от использования «чужих» адресов памяти, защита от записи в сегмент, не предназначенный для этого (сегмент кодов, сегмент толък о для чтения). Рассмотрим алгоритм вычисления линейного адреса памяти в защищенном режиме на примере команды MOV
[ЕВХ * ESI * 4 + 165]. ЕАХ
без учета уровней привилегий сегментов данных и команд. Пусть необходимо вычислить адрес памяти [ЕВХ + ESI * 4 * * 165]. Перед выполнением команд программы информация о глобальной и локальной дескрипторных таблицах записывается в регистры GDTR и LDTR, соответственно. В регистре GDTR находится информация об адрсге начала GDT и ее размере. LDTR содержит смещение в GDT дескриптора, который соответствует LDT, В дескрипторе находится информация об адресе и размере LDT. Рассмотрим порядок вычисления адреса: — так как по умолчанию с данными ассоциируется сегментный регистр DS, по этому регистру определяется таблица, где описан этот сегмент (GDT или LDT и номер строки в этой таблк- { це). При первом использовании регистра DS требуемая таблица I читается. Напоминаем, что младший бнт регистра DS определяет тип этой таблицы. Если в этом битс записано число 0, то испо.ть- I зуется GDT, иначе LDT. Номер строки в соответствующей таблпде определяется старшими 13 битами регистра DS; — если соответствующая строка не является частью таблицы (в таблице меньше строк, чем заданный номер), то ошибка доступе; — если соответствующая строка не является дескриптором (все поля строки нулевые), то ошибка доступа; если дескриптор не соответствует сегменту данных, то ! ошибка доступа; если для сегмента пе разрешена запись, то ошибка доступе; - вычисляется значение выражения ЕВХ + ESI '4 + 165 и сравнивается с допустимым адресом с учетом адреса начала я пределе сегмента. Вели значение выражения выходит за пределы допустимого адреса, то ошибка доступа. Полученное значение называется линейным адресом52
Если содержимое сегментного регистра не изменяется, шаги 1-4 не выполняются. Линейный адрес используется в качестве исполнительного адреса, если режим страничной адресации [сл. 6 - 2 . 2 ] отключен. Как следует из приведенного алгоритма, доступу к памяти предшествует группа проверок, которая защищает от использования «чужих» областей памяти и от выполнения запрещенных операций. Так как адрес начала сегмента зпдается в дескрвпториой таблице, а в команде задается только смещение относительно этого адреса, то перемещение сегмента в памяти легко может быть выполнено без изменения самих команд за счет изменения адреса начала сегмента. Такой способ использования сегментной адресации является наиболее надежным, но требует для каждого щтоженля составлять заново LDT и модифицировать GDT, что существенно усложняет управление программами. 2.6.3. Особенности использования данных и команд с учетом уровней привилегий в защищенном режиме Как следует из предыдущего пункта, каждый сегмент программы (данных, стека, команд) имеет уровень привилегий О — 3. Насоминпем. что уровень 0 соответствует наиболее привилегированным сегментам н используется ОС. Уровень привилегии 3 используется приложениями пользователя. Правила применения уровней 1,2 определяются ОС, сегменты с такими уровнями привидегий могут не использоваться1 (UNIX). Рассмотрим правили использования данных, стека и команд для раэвых уровней привилегий. Напоминвем, что уровни привилегии задаются: — в селекторе, т.е. сегментном регистре, этот уровень привилегии называется требуемым уровнем привилегии (Fcqucsted Pnullegr Level RQL). — s дескрипторе соответствующего сегмента, такой уровень привилегии называется даскрипторным уровнем привилегии [VeicriptorPnvilege Level
—
DPI.).
— it сегментном регистре, соответствующем текущему сегненту кода, — такой уровень привилегии называется текущим уровнем привилегии (Current Privilege Level — CPL). 1
Питфпр.чмчо ИРМ . ВИСНМЫР ОТ на пол «.дуют только два урчвня принплргнГи так Мк остлльаые уровни могут не поддержнвиться процегсоранп53
Для определения действующего уровня привилегии сегмент» процессор из DPL и RPL выбирает численно наибольший (т.е. смнимальными правами). Вычисленный таким образом уровень привилегии называется эффективным уровнем привилегии (Efftf tive Privilege Level — ЕРЬ). Н и ж е будут рассмотрены допустимые и недопустимые соотношения между уровнями привилегий для сегментов данных, стека и команд. Классификация команд • зависимости от текущего уронив
Привилегий Команды называются привилегированными, если их можно выполнять только на О уровне привилегии. К таким командам относятся: команды д л я изменения содержимого системных бита! регистра флагов (EFLAGS — см. 52); — команды для работы г GDT и LDT 1 ; — команды для работы с управляющими регистрами, определяющими режимы работы процессора 2 ; — команды для работы с отладочными регистрами: — команды для управления кэш [6.2.3]. Системные биты регистре флагов
До сих пор регистр EFLAGS использовался как храни ливр признаков выполнения предыдущей команды, таких как перенос (Сапу Flag), ноль (Zero flag) и т.д. Рассмотрим некоторые системные биты регистра флагов. 1. Бит трассировки (бит 8). Если этот бит установлеп, то после каждой команды прерывается выполнение программы. Это позволяет реализовать покомандный режим выполнения программы (трассировку). Используется отладчиками. 2. Бнт разрешения прерывания (бит 9). Используется для управления внешними устройствами. Если этот бит сброшен, пре рывание для всех внешних устройств игнорируется, программа at реагирует на работу таймера, клавиатуры и т.д. 1 Допускается использование в пользовательском режиме (PL 3) некоторых » мнпд. позволяющих получить информацию о полях дсскрипторноО тяйлпцмбп I Ux изменения. плпример, для определения байте доступа используется xovaejj IJK.R. Уроаеш, допустимых привилегий для некоторых комкид может меняться с МОЩЬЮ упряняяюших регистров, например, уровень привилегии для команды RDTSC можно изменить до уроапя 3 с помощью бита 2 регистре CR-1
3. Биты разрешения ввода-вывода IOPL. Рассмотрены выше (сл. 2.2.3). ДЛЯ современных ОС в этих битах, к а к правило, стоит О. Поскольку эти биты, как и предыдущий, по сути, связаны с возможностями работы с внешними устройствами, этот уровень привилегии задает достаточные права д л я изменения бита 9. 4. Бит вложенной задачи (бит 14) [3.2.6]. Устанавливается, если задача вложенная, т.е. требуется возврат в программу, из которой была запущена задача. Устанавливается, если запущена новая задача с помощью команды CALL или вызвана программа для исполнения запроса внешнего устройства (прерывание). Устанавливается аппаратно при вызове вложенной задачи. Сегменты данных
Для сегмента данных определяется уровень привилегии по сегментному регистру для данных (DS, ES, FS, GS) и соответствующему дескриптору, используя численно максимальный. Правило 1. В программе разрешается использовать данные с уровнем привилегии численно большим или равным текущему уровню привилегии. В соответствии с этим правилом, доступу к данным предшествует вычисление уровня привилегии сегмента данных PLd по формуле: PLd = max (PLsr,
PLd),
где: PLsr— уровень привилегии, заданный в сегментном регистре для данных; PLd — уровень привилегии, заданный в соответствующем дескрипторе. Доступ к данным запрещен, если: PLd < CPL,
где: FLj) — уровень привилегии сегмента данных; CPL — эффективный уровень привилегии. Таким образом, обеспечена возможность доступа модулей операционной системы к данным пользовательских программ, но не наоборот. Это правило обеспечивает невозможность изменения данных ОС из программ пользователя. Стеки
Особую роль при выполнении программ имеет стек. Стек не только использует свои правила добавления и удаления элементов, 55
но и правило доступа с учетом уровня привилегий отличается я правила доступа для обычного сегмента данных. Правило 2. В программе разрешается использовать сте* только с уровнем привилегии численно равным текущему уровню привилегии. В соответствии с этим правилом, доступу к стеку предшествует вычисление уровня привилегии стека PL$ по формуле: PLS = max (PLss,
PLd),
где: PLss — уровень привилегии, заданный в сегментном регистре для стека; Pf-d — уровень привилегии, заданный в соответствующе* дескрипторе. Доступ к данным запрещен, если: PLS*CPL.
где: PLs — уровень привилегии стека; CPL эффективный уровень привилегии. Таким образом, если в системе выполняются приложения, использующие разные уровни привилегий, в ней должны быть стеки для этих уровней, т.е. каждому уровню привилегий соответствует свой стек. Стеки должна опредечить операционная систем для всех допустимых уровней привилегий. Сегменты кеда
Как известно из разделов программирования, допускает вызов функций, расположенных в других сегментах. Примерена таких функций являются функции из DLL. В этом случае возможно, что уровень привилегий д л я гегмепта с вызывающей программой не совпадает с уровнем привилегии кодового сегмеша с функциейПравило 3. В программе разрешается использовать команды с уровнем привилегии численно равным текущему уровню привилегии. Это означает, что из приложения пользователя мы ыоже* вызвать функции с уровнем привилегии 3 и не можем вызван функцию с любым другим уровнем Привилегии. В соответствии с этим правилом, доступу к функции из другого сегмента предшествует вычисление уровня привилегии сегмента с функцией PLc по формуле: 56
PLC = max (PLCS,
PLd),
где: PLcs — уровень привилегии, з а д а н н ы й в сегментном регистре для функции; PZ-d — уровень привилегии, з а д а н н ы й в соответствующем дескрипторе. Доступ к данным запрещен, если: PLc*CPL,
где: PLC — уровень привилегии ф у н к ц и и ; CPL — эффективный уровень п р и в и л е г и и . Исключения. 1. Если для кодового сегмента установлен ф л а г «Согласованный сегмент», то сегменту присваивается уровень п р и в и л е г и и , равный уровню привилегии вызывающей п р о г р а м м ы . 2. Для вызова функции с большими привилегиями (уровень привилегии численно меньше), используются специальные шлюзы. Исключение 1 позволяет и с п о л ь з о в а т ь одну б и б л и о т е к у с функциями графического интерфейса д л я модулей я д р а операционной системы (уровень п р и в и л е г и и 0) и модулей пользовательских программ (уровень п р и в и л е г и и 3). Так к а к фактически уровень привилегии вызывающей и в ы з ы в а е м о й п р о г р а м м в этом случае становится одинаковым, то д л я передачи параметров используется стек вызывающей п р о г р а м м ы . З а м е т и м , что сам согласованный сегмент должен иметь в дескрипторе уровень привилегии, численно меньший и л и р а в н ы й т е к у щ е м у уровню привилегий. Исключение 2 позволяет вызывать ф у н к ц и и операционной системы (так называемые системные вызовы) из пользовательских программ. Рассмотрим р е ш е н и е п р о б л е м ы стеков в этом случае. Так как на каждом уровне привилегии используется свой стек, параметры из стека вызывающей п р о г р а м м ы д о л ж н ы быть скопированы в стек с уровнем привилегии ф у н к ц и и перед вызовом и в обратном направлении после возврата. Это к о п и р о в а н и е выполняется самим процессором. Естественно, е м у необходимо «знать» количество этих параметров и адреса стеков. Количество параметров задается в самом шлюзе. Так к а к д л я количества параметров отводится только 5 бит, м а к с и м а л ь н о е число параметров для системных вызовов должно быть не более 32. Кроме числа 57
параметров, в шлюзе задается адрес точки входа вызывает* функции. Шлюзы задаются в таблицах дескрипторов. Уромв| привилегии шлюза должен быть равен уровню привилегии it зывающей программы. Таким образом, операционная гнета*» может задать разные шлюзы для разных уровней привилетЛ что дает возможность изменять адреса точек входя для различи." уровней привилегий, что фактически обычно приводит к cyir нию или расширению функциональности. При вызове функодп адрес стека вызывающего модуля записывается в новый стекаю сте с параметрами. Использование различных уровней привилегий позвешгустановить дополнительные механизмы защиты между прилонЯ ниями, выполняемыми на разных уровнях привилегий. Так.щ» ложення пользователя не могут напрямую работать с данный операционной системы (данными режима ядра), вызов фуыкц4 операционной системы (системные вызовы) осуществляется черв дополнительные шлюзы, что обеспечивает возможность конт] лнруемого перехода к разрешенной точке входа. 2.6.4. Переключение между реальным и защищенным режимами Так как современные операционные системы обычно фуа—| ционируют в защищенном режиме, первой функцией ОС до<яа быть переключение из реального ражима в ващищенный Для переключения в защищенный ражим необходимо полнить следующие действия: — подготовить таблицу глобальных дескрипторов GDT; — сформировать содержимое регистра для GDT; — отключить внешние прерывания от внешних устройся; — установить признак защищенного режима; — выполнить переход на сегмент, выполняемый в зощшд ном режиме. Для возврата в реальный режим достаточно установить п» знак реального режима и выполпить переход не сегмент, опрленный как сегмент реального режима. Подготовка т а б л и ц ы CDT
Б таблице необходимо определить все сегменты, которые • пользуются в программе при работе в защищенном режиме. В| вая строка GDT должна содержать только нулевые поля. Ка«
строка таблицы, кроме первой, должна соответствовать одному сегменту. Структура строки дескрипторной таблицы представлена ниже: STRUC descriptor Ы_0_15 dw О base 0_15 dwO baseJ6_23 db О access dbO limit_16_19 db 0 base 24 31 db 0 ENDS descriptor
16 битов предела сегмента (младшие) 16 битов адреса сегмента (младшие) 8 битов адреса сегмента (средние) байт доступа 4 бита предела сегмента(старшие) 8 битов адреса сегмента(старшие)
Как видно из приведенной структуры, значение адреса начала сегмента задается тремя полями ( b a s e _ 0 _ 1 5 , b a s e _ 1 6 2 3 , base_24_31), а предел — двумя ( l i m i t _ 0 _ 1 5 , l i m i t _ 1 6 _ 1 9 ) . Это является «наследием» 16-битных процессоров, когда считалось, что размер сегмента в 16 бит и общий размер памяти, задаваемый 24 битами, вполне достаточны. Необходимость расширения этих значений без нарушения совместимости с младшими моделями потребовала использовать продолжения полей после байта доступа. Вот почему фирма INTEL отказалась от совместимости с младшими моделями процессоров для 64-битных процессоров. Поле предела сегмента равно размеру сегмента — 1. Может быть задано больше, чем реальный размер сегмента. Так к а к дескрипторная таблица задается в реальном режиме, то поле адреса вычисляется по правилам вычисления адреса в этом режиме, т.е. содержимое сегментного регистра * 16 + смещение. В вычисленном адресе выделяются 16 бит, 8 бит и 8 бит и записываются в соответствующие поля структуры. Так как адрес начала необходимо записать для всех сегментов, рекомендуется использовать макрос для вычисления этого адреса (попробуйте самостоятельно составить этот макрос!). Байт доступа определяется типом сегмента и имеет структуру, начиная с младшего бита: — признак наличия доступа к сегменту ( в н а ч а л е м о ж е т быть 0); — разрешение записи для сегмента данных (стека) и разрешение чтения для сегмента кода; — стек/данные или признак согласованного сегмента (напоминаем, что согласованные сегменты применяются при 59
необходимости использовать одви и те же функции дд< работы с вызывающими программами с разным уров~.« привилегии); — тип сегмента (для сегмента кода 1, для данных и ка О); — признак несистемного сегмевта (системными считают TSS. шлюзы, LDT,...). Сегменты с кодами, данными не» ком считаются несистемными независимо оттого, како! приложению соответствуют эти сегменты, в том чй и ядру ОС; — уровень привилегии сегмента (2 бита). Для сегментов, v спечивающих переключение в защищенный режим, д жен быть задан уровень привилегии равный О; — признак наличия сегмента в памяти. Так как в реально, режиме страничная адресация выключена, нет возможв сти загружать сегменты в память, ПОЭТОМУ все сегмевл. обеспечивающие переключение в защищенный ре> •> должны присутствовать в памяти. Значения байтов доступа для сегментов кодов и данных: CODE_ ACCESS
EQU
DATA_ACCESS
EQU
10011010В 10010010В
.несогласованный сегмент коде, DPL.сегмент данных для записи,
DPL-€
Пример. Пусть необходимо переключиться в эащищеви режим, вывести на экране пробелы белым цветом на черном фов в верхней половине экрана в текстовом режиме. Далее необхо.» j мо возвратиться в реальный режим и вывести пробелы черным цветом на белом фоне в нижней части экрана. Для данного примера требуются следующие сегменты: сегмент кода для работы в защищенном режиме (GD7 PM_CODY.
сегмент кода для переключения в реальный режим (GDI RM_COD)~, сегмент дапных для работы с видеопамятью в текстов i режиме (CD TPMDA Т). Определим дескрипторную таблицу для этих сегментов: I GDT NULL GDT_PM_COD G DT_RM_CCD GDT PM DAT
descriptor descriptor descriptor descriptor
<>
<0FFFFH..,CODE_ACCESS.10000000B> <80*25"2-1800QH,OBH.DATA_ACCESS, 100011»»
Для каждого сегмента задан максимально возможный • мер для 16-битного приложения OFFFFH. 60
Поля адресов в таблице д о л ж н ы б ы т ь с ф о р м и р о в а н ы про1раммно. Формирование регистра д е с к р и п т о р н о й т а б л и ц ы
В регистр необходимо записать 32-битный адрес с т р у к т у р ы , «держащей: — предел GDT, т.е. размер т а б л и ц ы — 1 (в н а ш е м примере в таблице 4 строки, каждая строка содержит 8 байт, следовательно, размер таблицы равен 32 байта, а ее предел — 31); — адрес начала таблицы — 32-битное число, в ы ч и с л я е т с я по правилам вычисления адреса в реальном р е ж и м е . Для формирования регистра используется к о м а н д а : LGDT [GDTADDR],
где GDTADDR — адрес начала описанной в ы ш е с т р у к т у р ы , определенной как PWORD. Выключение прерываний
В реальном режиме используются в н е ш н и е устройства, такие как таймер, клавиатура, д и с к и ... Д л я о б с л у ж и в а н и я э т и х устройств в реальном режиме и с п о л ь з у ю т с я о б р а б о т ч и к и прерываний BIOS, которые я в л я ю т с я 1 6 - б и т н ы м и п р о г р а м м а м и . После переключения в защищенный р е ж и м эти ф у н к ц и и не могут использоваться для обработки запросов в н е ш н и х устройств. Поэтому необходимо отключить о б р а б о т к у з а п р о с о в в н е ш н и х устройств. Для отключения обработки запросов ( м а с к и р о в а н и я внешних прерываний) используется команда CLI. Включение защищенного р е ж и м а
Для включения защищенного р е ж и м а необходимо: — установить младший бит регистра CRO в 1; — выполнить команду перехода на сегмент д л я в ы п о л н е н и я кода в защищенном режиме. Для установки бита управляющего регистра в 1 необходимо выполнить это таким образом, чтобы не и з м е н и т ь остальные биты этого регистра. Для этого можно использовать к о м а н д ы : MOV EAX, CR0 OR EAX, 1 MOV CRO, EAX
Для передачи управления требуемому сегменту (в н а ш е м примере это сегмент GDT_PM_COD) м о ж н о использовать к о м а н д у : MP FAR PTR 0ООО8Н:ООООН
61
Сегментный компонент команды перехода равен 8. что со.-* ветствует второй строке GDT. Смещение равно О, так как в пыф начале этого сегмента находится код. Программа для перехода в защищенный режим для TASM 5.1 пли выше представлена в Приложении 1 Переключевяе режимов работы процессора. Для компиляции и компоновки этс! программы необходимо использовать 16-битный компилятор. Командный файл: TfiSM
Имя модуля
TLINK
Имя модули
Для выполнения программы необходимо использовать DOS. а не DOS-режим 32-битной ОС. В результате выполнения программы получим экран, пом вина которого заполнена черными, а вторая половина — белый пробелами. Так как для большинства современных процессоров сбес»' чивается аналогичная поддержка ОС, определим возможвоспР процессора, которые необходимо учитывать при разработке ОС Рассмотренные архитектурные особенности процессора соназывают, что на аппаратном уровне, независимо от приоритет сегментов и их типов, обеспечиваются следующие возможности: — определение прав доступа для сегмента (тип сегмента, Ш; доступа); — определение границ сегмента. Таким образом, процессор защищает сегменты с учетом и' уровней привилегий (0..3), не позволяет превышать предел* сегмента и использовать сегмент в режиме, не соответствующе типу сегмента (например, использовать сегмент данных кик стгмент кода). Это существенно упрощает модули защиты валял от взаимного влияния программ в многопрограммном н мволпользовательском режимах. Напоминаем, что для обеспечевп совместимости с другими типами процессоров, которые обеся»чивают только два уровня привилегий, многоплатформенные ОС используют только 2 уровня привилегий процессора типа IA-32 О для режима ядра и 3 для режима пользователя. Реальи » режим процессора в современных ОС не используется в смя с ограниченностью адресного пространства и его полной везаиэч {Ценностью. Так как в пользовательском режиме используется• уровень привилегий, а в режиме ядра — О уровень приввлег 62
••ре*точение между этими уровнями может быть выполнено при м — функций через шлюзы. Второй способ переключений с почетно задач будет рассмотрен в следующем разделе.
2.7. О р г а н и з а ц и я у с т р о й с т в Pll аотрим организацию устройств ввода-вывода, т.е. П*Р„ предназиечетшх для передачи информации между а^едссором (памятью) и внешними носителями информации. Выше было сказано, что управление токими устройствами внк-лнается автономными средствами, а не основным процес. ом. Рассмотрим различные схемы организации внешних уст-
2.7.1. Контроллеры и драйверы устройств Д.1К обеспечения параллельной работы внешних устройств j at пралъного процессора используются специализированные . j j v c o p u ввода-вывода, которые называются контроллерами I , I тв. Контроллеры устройств различны дли различных типов | ч|ств Например, есть контроллер клавиатуры, контроллеры /«•w.' lit жесткого дисков и др. Однотипным устройствам может [«етстновать один контроллер. Контроллер управляет операцишл передачи ипформации для этого типа устройства, выполлагг «1раш1чешюР количество команд. Так. контроллер клавиатуры определяет состояние клони ян (шлсатое и отжатие) и номера нажатых клавши (скан коды). иоякв соответствия между символом и номером нажатой клашшд выполняется программой операционной системы. I • I ичным контроллером является контроллер диска. При moo 16ННП команды «Запись блока данных» он преобразует эту иггцоуровнсвую команду в низко-уровневые команды, такие как «и- шловнрование головки диска ни необходимую дорожку» и • •чпись данных на дорожку». Современные контроллеры дисков .-яые. так как овп хранят данные в кэше и могут изменить пори «к запросов к диску для оптимизации перемещения головки. |:
Программа ОС. используемая для управления внешними 1СТМЫК. называется драйвером. Драйвер обрабатывает оавввмые ему запросы от вышестоящих программ, передает
команды контроллеру, обнаруживает и обрабатывает ошнбк связанные с выполнением операции ввода-вывода. 2.7.2. Синхронный ввод-вывод
Ввод-вывод называется синхронным, если очередная ввода-вывода операция выполняется только после завершенг ввода-вывода, т.е. параллелизм фактически отсутствует. Едини., передаваемой информации зависит от устройства. Например, я клавиатуры такой единицей я в л я е т с я один символ (символы' устройство), для диска — сектор (блоковое устройство). Казед устройству ставится в соответствие состояние этого устройств которое позволяет взаимодействовать устройству и его контроль ру. Информация о состоянии устройства зависит от конкретн устройства, но для всех устройств можно определить: готовно устройства, конец операции, успешность выполнения операци Д л я управления контроллером процессор должен иметь ва. можность выполнять операции ВВОД (in), ВЫВОД (out) и ко роль состояния устройства. В скобках заданы соответствуют! команды процессора типа IA-32. Д л я каждого устройства опрел лен порт (порты), в котором (которых) записывается информат о состоянии процессора. Д л я контроля состояния устройства статочно прочесть содержимое этого порта (портов) (in). Схема программы для ввода массива символов, состоящл из п символов 1 : boot InputOutputEnd = false; for (Int i = 0; i < n; i++){ while (Устройство не готово) Ожидание; Чтение символа s[i];
}
InputOutputEnd = true;
Если используется буфер для записи вводимых-выводимь данных, то операция о ж и д а н и я выполняется не после кажд п символа, а после завершения операции целиком или заполнена! буфера. Примером т а к и х устройств с буфером является клави» тура. Буфер клавиатуры представляет собой кольцевую очеред.. 1
Предполагается, что одна операция выполняет чтение одного символа.
64
t вп плер возвращает критические состояния очереди, такие •очередь пустая» при попытке чтения из очереди и «очередь чиая« при попытке записи очередного символа в буфер. Недостаток синхронного ввода-вывода: процессор простаиваг в ожидании завершения операции ввода-вывода. 2.7.3. Асинхронный в в о д - в ы в о д
В этом разделе рассматривается организация асинхронного вывода на аппаратном уровне. П р о г р а м м н а я р е а л и з а ц и я linpoHHoro ввода-вывода рассмотрена в 8.9.3. Благодаря наличию контроллера устройств ввод-вывод моет выполняться независимо от Ц П . Д л я определения момента жрения выполнения операции ввода-вывода используется аинзм прерываний, рассмотренный ниже. В этом случае ЦП и г роллер могут работать параллельно. Алгоритм асинхронного ввода-вывода. 1. Определяется тип устройства для выполнения ввода-вы• да. 2. Запускается требуемый контроллер. С этого момента оба .-[> дессора (контроллер называют специализированным процессом) работают параллельно. 3. После завершения операции ввода-вывода работа ЦП преГ пается. По сигналу прерывания ЦП узнает о завершении операции ввода-вывода и ее успешности. Ниже прерывания рассмотрены более подробно.
2.8. Прерывания. Методы и реализации 2.8.1.Основные определения. О т л и ч и я м е ж д у о б ы ч н ы м и функциями и о б р а б о т ч и к а м и п р е р ы в а н и й
Прерывания — это такие события, при которых процессор прекращает выполнение текущей программы и выполняет специальную функцию — обработчик прерывания. Чем обработчик прерывания отличается от обычной функции? Вызов обработчика выполняется обычно1 в неизвестный момент времени, например, ' Допускается программный вызов обработчика прерывания, в этом случае говоТ о его синхронном вызове.
65
при нажатии клавиши вызывается обработчик прерываня!» клавиатуры. Поэтому о прерывании говорят как об асият . событии. Рассмотрим фрагмент кода для IA-32: МО V EAX.pq CMP EAX. ЕВХ JZ SHORTM1 Пусть прерывание возникло после команды CMP ЕАХ, * В этом случае, если сохранится только адрес возврата, что няется по команде call, то после возврата к команде JZ SHOP, она может быть выполнена неверно, если не сохранить флагшщ регистр. Таким образом, при вызове обработчика прерви необходимо сохранять полную информацию. оСеспечиаин возможность продолжения выполнения прервавной проОбъем этой информации является платформенно-эавнс —Л Для IA-32 — это адрес возврата н флаговый регистр. В зависимости от причины, по которой прерывается шял. нение программы, обработчики делятся на обработчики пси» ния и прерывания. Исключения порождаются процессоров,^ при выполнении кода возникает ошибка. Примеры ошибо». • ние па ноль, обращение к недопустимой команде, эаданнее стимого адреса памяти и т.д. Прерывания могут выэыватьс< внешними устройствами (аппаратные прерывания, напри нажатие клавиши), так и самой программой (программки щ рывавия). Программные прерывания, в принципе, немногий личаются от обычных функций, но для пх вызова (возбуждя* используются команды, отличные от команд вызова фувщ# Аппаратные прерывания - способ, с помощью кот,г внешние (относительно процессора) устройства могут влиял » работу процессора, например, сигнализировать ему о аавер I• кванта времени (прерывание таймере). Рассмотрим работу программы и обработчика иреры» •«I примере использования клавиатуры. Пусть во время выполнения некоторой программы яшш клавиша. В этом случае: — контроллер клавиатуры определяет с кии-код вазы •» клавиши; — запускается обработчик прерывания для клавивтц* обрабатывающий скан-код с целью определения кода наш ш 6Г)
••«вола с учетом одновременно н а ж а т ы х у п р а в л я ю щ и х к л а в и ш , тыхкак Caps Lock, Shift; - определяется нажатие комбинации с п е ц и а л ь н ы х к л а в и ш , пихт Ctrl/Alt/Del. В результате выполнения обработчика п р е р ы в а н и й д л я кла* рыопределяется код нажатой к л а в и ш и (не скан-код, а код!). 3i. ie завершения работы обработчика п р е р ы в а н и й в ы п о л н я тся возврат в прерванную программу. Е с л и в этой п р о г р а м м е угречается функция ввода символа, ей передается код н а ж а т о й (.«виши. Если встречается функция ввода символа, а н а ж а т и я и ваши нет, то ОС прерывает программу до тех пор, пока символ •лет введен
Все внешние прерывания подразделяются на маскируемые, г. прыеможно игнорировать, к. немаскируемые. Термин «маски| -оние» означает отмену данного типа п р е р ы в а н и й (игнорирова). Невозможно отменить п р е р ы в а н и я , с в я з а н н ы е с очень лозными причинами, такими к а к отключение электроэнергии. Порывание, которое невозможно игнорировать, н а з ы в а е т с я не• кируемым. Для современных процессоров м о ж н о в ы п о л н я т ь члкирование отдельных прерываний и л и всех в н е ш н и х м а с к и Цшых прерываний вместе. Так, д л я IA-32 м а с к и р о в а н и е всех •апшх прерываний, которые можно замаскировать, в ы п о л н я я < командой СИ. Для управления прерываниями используются: -программируемый контроллер прерываний (Programmable hirrrupt Controller — PIC), который в ы п о л н я е т централизован*»• давление прерываниями для однопроцессорных и многоакцессорных систем; -усовершенствованный программируемый контроллер преданий (Advanced Programmable Interrupt Controller — APIC), г"орый выполняет управление п р е р ы в а н и я м и конкретного проще пра для многопроцессорных систем. Контроллер прерываний в ы п о л н я е т с л е д у ю щ и е о с н о в н ы е г акции: — по запросу внешнего устройства (контроллера устройства) Л) IT этот запрос в очередь к заданному устройству, если не замаскированы прерывания для данного устройства; — с учетом уровней привилегий устройств запускает обраЬтики прерываний из очереди запросов; - если во время выполнения обработчика п о я в и л с я запрос ва обработку от более приоритетного устройства, то приостанав67
ливает выполнение текущего обработчика и запускаете* tl приоритетный; — маскирует обработку прерываний для отдельны! п ройств; — определяет номер прерывания, соответствующий дам устройству (соответствие между номером прерывания и ввав устройством может быть перепрограммировано). Таким образом, контроллер прерываний играет рать i жерв для всех внешних прерываний. 2.8.2. Обработка прерываний Для определения обработчика прерываний (функцаа, * торвя вызывается для данного прерывания), необходимо « номер прерывания, который также называется вектором q рывания. Для аппарвтных прерываний контроллер прерыи определяет соответствие между номером прерываний в уец ством. Для исключений номер прерывания определяет™1 * причиной, например, для деления на О в процессорах IA-ai пользуется вектор прерываний О. Для программных прерым номер прерывания задается в команде, например, по кош int 25 в процессоре 1А-32 вызовется обрвботчик для врерьшв 25. Обычно, для программных прерываний испольэуютса ai pa, не занятые аппаратными прерываниями и исключена! Для номере прерывания в команде INT отводится один бас- л этому диапазон изменения померв прерываний для LA-32 0. М По номеру прерываний и таблице прерываний процессоропра ляет адрес обреботчика. Таблица прерываний в случае использования процеа типа IA-32 в реальном режиме находится в начале области пл (начинается с адреса О) и состоит из 256 абсолютных (сегыенка щение) четырехбайтных адресов процедур-обработчиков Т ца прерываний в случае использования процессоров типа 1А ^ в защищенном режиме называется дескрипторной таблицеА f рываний IDT (Interrupt Descriptor Table). Каждая строка твйш< соответствует обработчику прерываний с заданным номера Таким образом, максимальный размер IDT — 256 дескриптвриИ Если максимальный номер обреботчика имеет номер и (п • 254 то можно задать только п дескрипторов. Если для вектора с ром m (m л) нет соответствующего обреботчика, то его дгс«»» тор должен содержать нулевые поля. 68
Адрес начала этой таблицы н а х о д и т с я в р е г и с т р е I D T R lermpi descriptors table register). В таблице дескрипторов IDT •crw быть дескрипторы трех типов: ш л ю з п р е р ы в а н и я ; ш л ю з УШКИ; Ш Л Ю З задачи. Тип дескриптора определяет поведение —раммы во время и после выполнения обработчика. П р и вызоК обработчика прерывания через ш л ю з п р е р ы в а н и я д а л ь н е й ш а я работа программы запрещается до з а в е р ш е н и я обработчика. При ! те через шлюз ловушки этого не происходит. Соответственно, j-иын метод больше подходит для а п п а р а т н ы х п р е р ы в а н и й (для ^сечения возможности монопольного у п р а в л е н и я устройством 1бежание повторного входа в ф у н к ц и ю обработки д л я з а щ и т ы тапаратных сбоев), а второй метод — д л я п р о г р а м м н ы х прер ваннп (которые в этом случае д о л ж н ы правильно работать при ориом входе в функцию до ее завершения). Такое свойство t.акции называется реентерабельностью. Напоминаем, что прерывания используются не только д л я ивления внешними устройствами, но и д л я обработки ошибок, н-прнмер, деление на 0, ошибка при обращении к п а м я т и (задан w сустимый адрес) и др. Дтя многопроцессорных систем п р е р ы в а н и я используются ""чью синхронизации доступа к общим ресурсам. В настоящее время механизм прерываний используется всем временными ОС. Обработчики прерываний для в н е ш н и х устройств непосредственно взаимодействуют с контроллерами этих устройств. Д л я мена информацией с внешними у с т р о й с т в а м и и с п о л ь з у е т с я адресное пространство ввода-вывода. К а ж д о м у в н е ш н е м у устрой,ву соответствуют фиксированные или н а с т р а и в а е м ы е номера портов, куда они записывают информацию и о т к у д а п о л у ч а ю т ,емые команды для исполнения. Это о с у щ е с т в л я е т с я с понощью соответствующих команд чтения и записи в порты. К а к W дет показано ниже, необходимо иметь определенный уровень привилегии для выполнения этих команд. В случае IA-32 обработчики прерываний д л я реального режима записаны в постоянном запоминающем устройстве (Basic InputOutput System — BIOS), что обеспечивает возможность начальной загрузки модулей ОС для переключения в з а щ и щ е н н ы й режим. Сразу после этого переключения необходимо определить обработчики прерываний для защищенного р е ж и м а , в противном | ^чае срабатывание таймера или н а ж а т и е к л а в и ш и приведет 69
к краху системы. Вот почему необходимо временно отключжпс прерывания (команда CLI) на время формирования IDT, IDTR 2.8.3- Исключения Как было сказано вы т е . исключение — вто особый вц I рывания. Оно возникает, если процессор не может продо vr работу в связи с ошибкой, например, деление на 0. обре щ к недопустимому адресу и т.д. Так как исключения явдш-ч следствием невозможности выполнения той или другой ко* т.е. возникают в известный момент времени, их вазывахп • хронными событиями, в отличие от асинхронных прерывна Существуют различные типы исключений. Так, для провд Щ разряда 1А-32 исключения бывают трех типов: fault (c6oi i М (ловушка) и abort (останов). Тип исключения зависит отзд когда процессор обнаружил ошибку, приведшую к ысключЯ и, следовательно, куда указывает сохраненный в стеке адр » врата, что, в свою очередь, определяет возможность продолжу программы после завершения прерывания. Исключение типа abort. Возникает, если надежное ваш новленис выполнения программы невозможно, адрес возвцк» флаговый регистр могут иметь ошибочные зкачения. Исключенпе типа fault. Адрес возврата указызает ва к ду, из-яя которой произошло исключение. После игпраьг ситуации возможно дальнейшее выполнение программы. Исключение типа trap. Адрес возврата указывает на < Ч ющую после «пойманной» инструкцию. После завершена* Ц ботчика программа может продолжать выполняться (кпк в программных прерываниях). Приведите примеры ситуаций, при которых возникает | дое из трех типов исключений, п проверьте правильность виц предположений по документации к процессору IA-32.
2 . 9 . И н т е р ф е й с ы I / O . П р я м о й д о с т у п к памяти 2.9.1. Интерфейсы I / O Интерфейс I/O служит для обеспечения аппаратной •.) между портами I / O и соответствующим контроллером устройств Он выполняет трансляцию значений, записанных в ад. • 70
1^ "рйвстве I/O (в портах), в команды и д а н н ы е д л я устройства, й тогивоположном направлении он определяет и з м е н е н и я состо I«I ч V тройства и, соответственно, обновляет порты I / O . Есть 2 типа интерфейсов. C u s t o m I / O i n t e r f a c e s соответ• ОДНОМУ устройству. В зтом случае контроллер устройства щ тожен там же, где и интерфейс. Эти устройства могут б ы т ь ми внутренними по отношению к компьютеру и л и в н е ш н и м и . Goiral-purpose I/O interfaces используется д л я с в я з и н е с к о л ь к и х жяних устройств. Рассмотрим более подробно к а ж д ы й из типов интерфейсов. Интерфейсы для отдельных устройств ( C u s t o m I / O i n t e r f a c e s )
Примерами такого интерфейса я в л я ю т с я и н т е р ф е й с ы д л я I .лиатуры, графической карты, диска, м ы ш к и и т.д. Интерфейс г. 'Биатуры, Keyboard interface, с в я з ы в а е т с я с к о н т р о л л е р о м I „внагуры, содержащим микропроцессор. Этот микропроцессор градирует нажатые клавиши, генерирует п р е р ы в а н и е и форми|'"т соответствующий скан-код. Интерфейс г р а ф и ч е с к о й к а р т ы Crophic interface используется вместе с соответствующим конт> пером графической карты, которая имеет свой собственный В|фер, свой специализированный процессор и код в постоянном »: яинаюгцем устройстве. Disk interface с в я з а н с д и с к о в ы м к а-роллером, который обычно интегрирован с с а м и м д и с к о м . || mouse interface связан со своим контроллером, в к л ю ч е н н ы м в *ышку. Интерфейсы общего назначения (General-purpose I/O interfaces) Современные вычислительные системы в к л ю ч а ю т несколько ш-ерфейсов I/O общего назначения, которые используются д л я ггппы внешних устройств. Наиболее о б щ и м и я в л я ю т с я парал->1ьный, последовательный и USB-порты. П а р а л л е л ь н ы й порт mallei port) обычно используется д л я принтеров, м о ж е т т а к ж е е .ппьзоваться для связи с другими к о м п ь ю т е р а м и , с к а н е р о м г.д. Данные передаются по одному байту (8 бит) в е д и н и ц у вре* к I. Последовательный порт (Serial port) аналогичен предыду3 чу, но за единицу времени передается один бит. Он включает медиальное устройство, которое преобразует байт в бит при отнлке и выполняет обратное объединение п р и приеме. Последиип интерфейс медленнее параллельного и н т е р ф е й с а , поэтому ад используется для устройств с невысокой скоростью работы, 71
например, модемы, м ы ш к и и др. U S B (Universal serial bus) рабом ет на высокой скорости, используется д л я внешних устройств,® пример, д л я ф л е ш - п а м я т и , э л е к т р о н н ы х ключей ( E T O K E N ) H I J К р о м е р а с с м о т р е н н ы х в ы ш е интерфейсов, к интерфеня! общего н а з н а ч е н и я относится SCSI ( S m a l l Computer System Мface), интерфейс д л я связи ш и н ы главного компьютера с вторт! ной ш и н о й , называемой SCSI-шиной. Позволяет соединить ш пьютеры, ж е с т к и е д и с к и , сканеры, CD-ROM. 2.9.2. Прямой доступ к памяти ( D M A )
Д л я обеспечения передачи д а н н ы х м е ж д у блочными вяж н и м и у с т р о й с т в а м и и п а м я т ь ю и с п о л ь з у е т с я дополнительна процессор Direct Memory Access Controller (DMAC). Будучи ami визированным CPU, DMAC м о ж е т п р о д о л ж и т ь передачу даннк» сам; когда передача д а н н ы х завершается, DMAC посылает за на прерывание. DMAC используется драйверами диска и другаt м е д л е н н ы м и устройствами, п е р е д а ю щ и м и большое количвчш байтов. Так к а к время з а п у с к а DMAC относительно велико, Л передачи небольшого числа байтов более эффективно испош! вать CPU.
2.10. Списки устройств и очереди драйверов К а к п о к а з а н о в ы ш е , к а ж д о м у устройству с помощьюРЯ присваивается соответствующий номер, который определяет (Я о б р а б о т ч и к п р е р ы в а н и й и п р и о р и т е т д а н н о г о устройства, (i управляет в н е ш н и м и устройствами с помощью драйверов, явль щ и х с я п р о м е ж у т о ч н ы м и м о д у л я м и м е ж д у внешними устрогай ми со своими контроллерами и пользовательскими программа*! Д л я установки соответствия м е ж д у устройствами и дрю i р а м и ОС формирует список устройств с указанием соответеив щ и х и м драйверов. Рассмотрим в качестве примера организацию списков vrJ ройств д л я ОС U N I X и W I N D O W S . 2.10.1. Организация списка устройств для ОС UNIX
К а ж д о м у устройству соответствует специальный файл (фиш устройства ФУ). ФУ д е л я т с я на 2 больших класса: первый кдш ф а й л о в д л я с и м в о л ь н ы х у с т р о й с т в , в т о р о й — для бЛОЧВИ ! 1
72
• ств. Каждому файлу устройства с т а в и т с я в соответствие Нцывфайл, который фактически с с ы л а е т с я не на д а н н ы е , Iидентификатор устройства. Кроме имени и т и п а устройства г" оиный или блочный), каждый файл-устройство имеет атриЬы.Majornumber — число в диапазоне 1 ... 254, о п р е д е л я ю щ е е « гройства. Обычно все ФУ, имеющие о д и н а к о в ы е з н а ч е н и я у/ number и одинаковый тип, у п р а в л я ю т с я одним и тем же !. озером устройства. Таким образом, Major number ф а к т и ч е с к и °т драйвер для управления данной группой устройств. Minor ш^ег - число, которое определяет конкретное устройство из ТГглы устройств, имеющих одинаковое значение Major number. Втабл 2.1 приведены примеры файлов-устройств. Примеры файлов-устройств (LINUX) (
Таблица
2.1
Ы
Тип
Главное число (Major number)
Дополнительное число (Minor number)
•yVO
Блочное
2
0
Гибкий диск
Блочное
3
0
Первый жесткии диск
у "xfe2 Блочное
3
2
Второй раздел первого ж е с т кого д и с к а
V ЮЬ 1
Блочное
3
64
Ur «sole
Символьное
5
1
Описание
Второй жесткий диск Консоль
Из табл. 2.1 следует, что все ФУ н а х о д я т с я в к а т а л о г е /dev. Hi' ie Major number определяет, что д л я у п р а в л е н и я г и б к и м дис| т используется драйвер, отличный от драйвера д л я ж е с т к о г о •ска. Для всех жестких дисков указано одно и то же значение number Дополнительное число (Minor number) определяет мер устройства в цепочке. Перед и н с т а л л я ц и е й очередного вера ОС проверяет наличие соответствующего Ф У . Е с л и ФУ aw, то соответствующий драйвер не и н и ц и а л и з и р у е т с я , поэтому атемныл администратор обычно включает все ф а й л ы устройств, ;г .висимо от того, какие устройства понадобятся. Б о л ь ш о й раз«••> каталога (порядка 1800 элементов) приводит к потере времев, связанной с поиском требуемого элемента, необходимого п р и a- IBOM доступе к файлу-устройству. 73
Вместо номеров устройств д л я современных версий I < могут использоваться имена этих устройств, например, д»-и устройствам соответствуют имена /dev/discs/discO. Фпктпчл го файла с данным именем не существует, имя нспольауг установки связи между устройствами и драйверами. ОС d таблицу соответствия файлового имени устройства и таблицу » тодов драйверов устройств. При регистрации драйвера устанавливается с между драйвером и физическим устройством, для упрошена* торым драйвер предназначен. Сам драйвер может быть L частью ядра или загружаться динамически по мере в ад оби»* В первом случае регистрация драйвера выполняетсв авто» ски при загрузке ОС. 2.10.2. Организация списка устройств для WINDOWS При загрузке ОС определяются устройства, подкл" ные к вычислительной системе. Это определение выполи» модулем N t d e t e c t . c o m в реальном р е ж и м е . Вся инфорч об обнаруженных устройствах хранится в централизма* базе данных Registry (реестре). Полная таблица устроЙсп, * энанных на этапе загрузки ОС, находится в реестре по и HKEY_LOCALMACHlNE\SYSTEM\CurrentConU& Control\Class\CriliculDeviceDaluBase. Все драйверы, должны быть загружены, находятся в каталоге HiNDO* Syslem32\driuers. Для каждого драйвера определен этап за ОС, на котором загружается заданный драйвер, и его тип. Эти грузки определяется полем с именем. Используются драйверы трех типов. Драйверы высокого уровня применяются для органам ввода-вывода на пользовательском уровне. Примерены « драйверов являются драйверы для конкретных файловых 'f например, NTFS, FAT и т.д. Эти драйверы не зависят от > -•< н и х типов жестких дисков, на которых они установлены. Промежуточные драйверы используются для фордороня и передачи данных на драйверы конкретных устройств. Л"' рами таких драйверов являются драйверы для группы Драйвером для группы устройств является драйвер кавсол.» торая включает в себя устройства ввода и вывода. Драйверы устройств управляют конкретными уси»* ми, например, клавиатурой. Менеджер ввода-вывода (I-'074
/!т»рпретпрует запросы ввода-вывода п о л ь з о в а т е л ь с к и х прогрел или ОС, определяет соответствующие номера обработчиков Ч»; ываиий, формирует стандартный п а к е т и п е р е с ы л а е т его «."/всеминеобходимыми слоями драйверов. С ф о р м и р о в а н н ы й иг f кодом возврата и данными, если в ы п о л н я л с я ввод д а н н ы х , елращается Менеджеру ввода-вывода. П о л у ч е н н ы е д а н н ы е п р и дойном завершении передаются программе, к о т о р а я сформировал запрос ввода-вывода. Для обеспечения независимости слоев выкгер должен быть готовым всегда п р и н я т ь н о в ы й запрос от ttf го другого драйвера (все запросы стандартные) и обрабатыцть состояние после выполнения запроса. Ц е п о ч к а драйверов, а вторым должен пройти запрос, образует стек ввода-вывода Ц ]stack). Функция lofillocatelrp позволяет создать п а к е т д л я оче? зого уровня драйвера. Для получения адреса очередного драйте в цепочке используется ф у н к ц и я loGetNextlrpStackLocation, та вызова драйвера с данным адресом — ф у н к ц и я loCallDriver. Заметим, что все функции начинаются с /о, и это говорит I , что данные функции я в л я ю т с я ф у н к ц и я м и м е н е д ж е р а г?"1а-вывода (I/0-Manager). Использование э т и х ф у н к ц и й вмеR вызова конкретных драйверов внутри данного драйвера обедаивает независимость драйвера от состава ц е п о ч к и драйверов. [, iee того, I/0-Manager имеет ф у н к ц и ю д л я д о б а в л е н и я драйва в любую цепочку драйверов. Единственное ограничение — I шисимости от типа драйвера он может быть добавлен в начало аночки (если это драйвер высокого уровня), в середину (промеf точный драйвер), в конец (драйвер устройства). 2.10.3. Драйверы устройств. О ч е р е д и д р а й в е р о в
Драйвер устройства — программное обеспечение д л я управляя ВУ. Так как большинство устройств и м е ю т у н и к а л ь н ы е с „.роллеры I/O, т.е. уникальные к о м а н д ы и флаги состояний, ш имеют свои драйверы. Перед использованием ДУ необходимо в ы п о л н и т ь следующие действия: зарегистрировать ДУ и и н и ц и а л и з и р о в а т ь его. Операция регистрации сводится к з а п о л н е н и ю т а б л и ц ы , в которой устанавливается соответствие м е ж д у устройством и драйvpoM, предназначенным для у п р а в л е н и я э т и м у с т р о й с т в о м . S л)й же таблице определяются обработчики о п е р а ц и й драйвера. Операция инициализации выполняется непосредственно перед 75
использованием дрнйвера. Операция инициализация в драйверу требуемые ресурсы, то есть закрепляет за внм и обработчики прерываний. Так как этими ресурсами о,!"1*' менно может пользоваться только один драйвер. веобхо^ выполнять выделение ресурсов непосредственно перед их и зованием и освобождать ресурсы, как только это возможно. | но функции драйвера проверяют, был ли ов ивициялиэ"» и если нет, то выполняют его инициализацию. Для опреа-- *«•» факта инициализации применяется обычно счетчик леи л ния. Если этот счетчик установлен в О, инициализации ве — она выполняется, счетчик увеличивается на 1. При повто>испольэовании драйвера другим процессом счетчик увел» I ется без повторной инициализации. Содержимое этого счет» используется при освобождении ресурсов. Фактическое ow • дение возможно только в том случае, если счетчик использа! равен 0. Команды освобождения ресурсов при ненулевом « нии счетчика только уменьшают содержимое счетчнка. При разработке драйверов используется послойная ттг» гия разработки, обеспечивающая упрощение драйвера на п • J из уровней и возможность незавпеимого изменения дрейвдмотдельном слое. Запросы передаются между слоями тр-*"— в соответствии с очередью драйверов, которая определяется» этапе загрузки. Примером многослойных драйверов явч драйверы для работы с жесткими дисками. Они могут вк.»• в себя следующие слои. Драйвер самого нижнего уровпя мв средственно работает с контроллером диска и выполняет а* ции чтения-записи секторов диска. Драйвер следующега Т;-1 • обеспечивает доступ к файлу с учетом конкретной файлов системы. Драйвер очередного уровня выполняет пользова*» ские запросы, которые не зависят от файловой системы * г ства.
2 . 1 1 . Стротегии б у ф е р и з а ц и и для Д У Традиционно ОС делят внешние устройства на бло — и символьные. К блочным относятся устройства, которые ваощ операцию I/O передают большое число байтов, например, -ш звуковая и сетевая карты. Для работы с такими устройств™ применяются 2 технологии; 7С
-использование DMA для передачи блоков д а н н ы х ; -использование циклического буфера из 2-х и л и более элег :я, каждый элемент имеет размер блока д а н н ы х . Когда слуш гея прерывание, сигнализирующее о том, что новый блок дан• и прочитан, обработчик прерывания устанавливает у к а з а т е л ь ii "чующий элемент циклического списка, т а к что с л е д у ю щ и е шные будут записаны в пустой блок. Напротив, когда драйвер -ооирует эти данные в адресное пространство процесса, соответтг.лщая позиция циклического списка освободится, т.е. будет Купна для записи нового элемента. Роль циклического буфера очень в а ж н а , т а к к а к если д а ж е —ожение пользователя выполняется не сразу ( в ы п о л н я е т с я боw привилегированное приложение), DMAC м о ж е т п р о д о л ж а т ь яглнять элементы циклического буфера, п о с к о л ь к у п р я м о й лети к памяти выполняется по поручению текущего процесса. Подобные ситуации случаются, когда п е р е с ы л а ю т с я п а к е т ы «сети, во в этом случае поток входящих д а н н ы х а с и н х р о н н ы й . Ъ еты посылаются независимо друг от друга, и и н т е р в а л времеII между двумя последовательными п а к е т а м и н е п р е д с к а з у е м . I рассмотренное относится к последовательным устройствам, как буфер не используется повторно: звуковое п р и л о ж е н и е не •кет попросить микрофон повторно передать блок д а н н ы х ; ана.лчно, сетевое приложение не может попросить сетевую к а р т у Iтрио передать пакет. С другой стороны, буферизация д л я устройств с произволь•ш доступом (диски всех видов) намного более с л о ж н а я . В этом «чае приложения имеют право попросить повторно прочитать i пзаписать блок данных. Кроме того, доступ к э т и м устройствам •т медленный. Эта специфика влияет на с т р у к т у р у драйвера ;гска. Буферы для устройств прямого доступа играют другую роль, «и используются для хранения данных, которые не необходимы пцессам сейчас, а другим процессам они могут понадобиться П "<е. Другими словами, буферы я в л я ю т с я основными компооттами программного кэша, который уменьшает количество до: гаев к диску.
2.12. Вопросы и задачи 1. Объясните понятие «виртуальная машина». Как виртуальные машины используются при разработке ОС? 77
3. ПАРАЛЛЕЛИЗМ
Цели изучения раздела: 1. Объяснить необходимость параллелизма внутри среды О С . 2 Продемонстрировать потенциальные проблемы времени исполнения, возникающие из-за наличия множества параллельных операций в отдельных задачах. 3 Описоть розничные механизмы, которые могут использоваться на уровне ОС для реализации параллелизма, достоинства каждого из ни*. 4 Объяснить различные состояния, через которые проходит задача, и структуры данных, необходимые для поддержки многозадачности. 5 Описоть различные подходы к решению проблемы взаимного исключения в ОС. 6 Объяснить причины использования прерывания, диспетчеризации и переключения контекстов в ОС. 7 Изобразить состояния и диаграммы переходов для простых примеров. 8 Обсудить применение структур данных, таких к а к стеки и очереди в управлении параллелизмом. 9 Описать условия возникновения тупиков.
3.1. Понятие параллельного исполнения 3.1.1. Параллелизм в системах аппаратного оборудования
Параллелизм заложен уже на уровне разрядов. Так, операция сложения числа реализована с помощью параллельного "гчкения с последующим учетом переноса. Команды процессора выполняются параллельно за счет использования конвейера и су79
3. ПАРАЛЛЕЛИЗМ
Цели изучения раздела: 1 Обьяснить необходимость параллелизма внутри среды О С . £ Продемонстрировать потенциальные проблемы времени исполнения, возникающие из-за наличия множества параллельных операций в отдельных задачах. 3 Описоть различные механизмы, которые могут использоваться на уровне ОС для реализации параллелизма, достоинства каждого из них. 4 Обьяснить различные состояния, через которые проходит задача, и структуры данных, необходимые для поддержки многозадачности. 5 Описать различные подходы к решению проблемы взаимного исключения в ОС. 6 Обьяснить причины использования прерывания, диспетчеризации и переключения контекстов в ОС. 7 Изобразить состояния и диаграммы переходов для простых примеров. 8 Обсудить применение структур данных, таких как стеки и очереди в управлении параллелизмом. 9. Описать условия возникновения тупиков.
3.1. Понятие параллельного исполнения 3.1.1. Параллелизм в системах аппаратного оборудования
Параллелизм заложен уже на уровне разрядов. Так, операция сложения числа реализована с помощью параллельного •ожения с последующим учетом переноса. Команды процессора выполняются параллельно за счет использования конвейера и су79
перскалярностп. Суперскалярность означает наличие вга блоков для параллельного выполнения операций. К с параллельное выполнение команд не всегда возможно по щим причинам: последовательные команды могут быть завис результатам. Это значит, что результат выполнения оче, менды зависит от результата выполнения предыдущей команды перехода нарушают порядок выполосни манд, поэтому результат выполнения следующей команды лируется; — современные процессоры используют специали ные блоки, т.е. для целочисленных вычислений, для ний с плавающей точкой, для операций умножения п др. в программе операции какого-то типа не используются, то ветствующие блоки простаивают. В связи с последним недостатком в современных • используется технология HYPER THREADING. Смысл нологии состоит в том, что параллельные устройства п используются не для выполнения очередных команд одя тока, а для выполнения разных потоков одного процесса разных процессов. В этом случае один физический п рассматривается ОС как несколько логических процесс ОС их использует для разных потопов. В этом случае о многоядерном процессоре. Пример такого процессора— сор ITANIUM. Процессоры внешних устройств работают параллеяья если одно приложение выполняет операцию вводе-вывода, гое — вычислительные операции. Это обеспечивает пя> • выполнение вескольких приложений даже на однопроц* системе. В многопроцессорной системе параллельно работают цессоры. По какому принципу может осуществляться мно ность? 1. Сама задача может время от времени передавать кие другой задаче. 2. Управление может поочередно отбираться у одной п передаваться другой задаче. Первый способ получил название кооперативной { няющей) многозадачности, а второй, используемый в 1 стве современных популярных ОС, вытесняющей мв ности. 80
3.1.2. Три параметра многозадачной вычислительной системы
Эффективность работы многозадачной в ы ч и с л и т е л ь н о й сиопределяется тремя параметрами: - пропускной способностью (количество в ы п о л н я е м ы х прогчлм в единицу времени); реактивностью (время отклика к а ж д о й запущенной про, ямы); динамичностью (способность обеспечивать удобство рабоv гльзователя в динамично меняющейся обстановке). К сожалению, эти параметры в з а и м н о и с к л ю ч а е м ы е . Это ,,• л- ю к разделению ОС на три типа, к а ж д ы й из которых обеспеiw^ наилучшее значение для одного из этих параметров. Наибольшую пропускную способность с точки з р е н и я одной ар ;раммы имеют системы пакетной обработки. В этом случае не •'"гнтся время на сохранение и восстановление текущего состояГ; 'пдачи при ее вытеснении. Но в этом случае процессор проставь во время выполнения операций, в которых он не участвует. Пересиленную часть своего выполнения программа затрачивает к шерации ввода-вывода (которые, к а к п р а в и л о , не требуют VWTHH вентрального процессора, а значит, могут в ы п о л н я т ь с я з;шетьно с программой). Пока одна из программ ожидает заК'.яния операции ввода-вывода, процессор исполняет другую jjurpaMMy. В результате многозадачность приводит к значительна (уплотнению» выполнения программ, а значит, и обеспечи•г; большую пропускную способность, чем характерное д л я си-»м пакетной обработки однозадачное выполнение программ по /н,- до. Таким образом, наилучшими с точки з р е н и я пропускной [«обности являются ОС с невытесняющей многозадачностью. Второй параметр — реактивность — обеспечивает время от1-ш (время выполнения) программы. Т.е. система, сделавшая р на реактивность (такие системы н а з ы в а ю т с я с и с т е м а м и реа лого времени), гарантирует, что п р о г р а м м а в ы п о л н и т с я Ч'лределенный промежуток времени. Третий параметр — динамичность — определяет удобство ра| ;ы пользователя, которому хочется работать одновременно с неаишькими программами интерактивно, причем неизвестно, когда вс какими. Т.е. алгоритмы распределения ресурсов компьютера в такой системе должны приемлемо себя вести с неизвестным .ранее количеством программ и запрошенным и м и количеством 81
ресурсов. Такие системы называются системами разделеяплчмени, и к ним относятся популярные WINDOWS, LINUX а| На первый взгляд кажется, что требования дивямнтве* и реактивности схожи, но только на первый взгляд. В спста. ренльиого времени заранее известно, какие программы буд]~ * пущены и какие ресурсы им потребуются, что позволяет шМ аффективно спланировать распределение ресурсов (следовгя» но, гарантировать, что в любой ситуации программа будет * полнена за определенный промежуток времени). В системы « деления времени никаких предположений о количестве и пори запуска приложений сделать нельзя. 3.1.3. Параллелизм в системах программного обеслечем Программы, которые выполняются параллельно, или усфй ства, работающие параллельно, как правило, не должны на »» друг о друге, ни мешать друг другу. Кроме этого, разные yef* ства могут работать с разной скоростью. С этой точки зреши-» ницы выполнения должны быть независимыми. Такой едн i работы является процесс. Таким образом, одно из опредпроцессов — независимые единицы работы, которые могут * полпяться с разной скоростью. Не все процессы должны быть независимыми. Возмояик 1 • бование взаимодействия между параллельно работающим ф цессами. Это взаимодействие осуществляется лишь по стро{% заранее определенным правилам. Заметим, что параллелизм может быть обеспечен не »Щ на уровне отдельных процессов, но внутри процесса за счет щ пользования языковых возможностей. Существует целая ч* параллельных вычислений и их использования для решения кретных задач. Некоторые языки программирования обеспея» ют задание участков кода, которые могут выполняться пера.*»'» во. В настоящее время, когда многопроцессорные системы спя популярными, эта проблема становится все более актуально!
3.2. А п п а р а т н а я п о д д е р ж к а многозадачного режима При разработке первых ОС многозадачность поддерж» шЩ только на программном уровне. Современные процессоры и> ратно поддерживают переключение задач. Этот механизм waft
iv"я для обработки прерываний и п е р е к л ю ч е н и я процессов. Йсиотрим эти средства для процессоров типа IA-32. 3.2.1. Переключение задач
Задача — единица работы для процессора, т.е. это единица, • вторую процессор может п е р е к л ю ч и т ь с я , приостановить, и уть. Это может быть утилита ОС или пользовательская лро-гмма. На аппаратном уровне решены следующие проблемы: охранение состояния текущей задачи; запуск задачи, начиная тачала или точки, где она была прервана при предыдущем искллении. Новая задача может быть запущена к а к ф у н к ц и я , т.е. «спечиваетсн возврат к предыдущей задаче после завершения иг данной (команда CALL). Можно запустить новую задачу без («ранения адреса возврата (команда JMP). Аппаратные средства выключения задач могут использоваться и часто используются ОС для поддержки механизма переключения между приложенной в случае многопрограммного или многопользовательского Мшюв, поэтому в данном учебнике рассмотрены эти средства на тгимере архитектуры 1-32. В дальнейшем будем называть старой задачу, которая выполЯ5=тпереключение, новой будем называть задачу, на которую выпивается переключение. Схема переключения между задачами помощью команд JMP и CALL представлена на рис. 3.1. Старая задача
JMP
Старая задача •
CALL
Новая задача Новая задача
>
Рис. 3.1. Переключение между задачами с помощью команд JMP и CALL При переключении задач используются следующие структура данных: -сегментсостояния задачи (Task Status Segment — TSS); - дескриптор сегмента состояния задачи ( T a s k Status Seg ml Descriptor— TSSD); - регистр задачи (Task Register — TR); - дескриптор шлюза задачи (Task Gate Descriptor); - NT-флаг в регистре EFLAGS. 83
3.2.2. Сегмент
задачи (TSS)
Используется для сохранения состояния задачи с целью обеспечения возможности продолжения ее выполнения. Прежде чем читать этот пункт, задумайтесь над тем, что необходимо сохранить, чтобы можно было возвратиться к прерванному приложению. Запишите, а затем сравните с информацией, хранимой в TSSВсе поля сегмента состояния задачи делятся на статически и динамические. Статические поля создаются при создании задачи и остаются без изменения вплоть до ее завершения. Состояеве динамических полей процессор изменяет в Процессе переключения . Сначала рассмотрим очевидные поля. 1. Общие регистры EAX, ЕСХ, EDX, ЕВХ, ESP, ЕВР, ЕЯ и£И Значения регистров постоянно изменяются. Динамические пом 2. Сегментные регистры (ES, CS, S S , DS, FS и GS). Определяют номера строк в дескрипторной таблице. Так как дескрипторная таблица задается на этапе создания приложения, содержим* этих регистров не изменяется- Статические поля. 3. Так как переключение задач может быть выполнено в л» бой момент времени, в том числе после команды сравнения н коменды перехода, необходимо сохранить регистр флагов EFLAGS содержащий условия перехода. Значение регистра изменяете! Динамическое поле. 4. Для возобновления выполнения задачи с очередной к манды необходимо сохранить ее адрес, который хранится в реп стре команд (Е/Р), поле динамическое. 5. Если ожидается возврат в старую задачу, т.е. для переютг чения используется команда CALL, то необходимо запомнить да сто расположения TSS для этой задачи. Все TSS хранятся в GDT. как системные сегменты. В TSS новой задачи необходимо заполнить место положения в таблице С DT TSS старой задачи (селенге; TSS старой задачи) (динамическое поле). 6. Нппоминаем, что с каждой задачей (приложением) свя» на не только GDT, но и LDT. Информация обо всех LDT храията в GDT, при этом LDT рассматривается как системный сегыен» определенного размера. В TSS необходимо запомнить место «ложения в таблице GDT, где находится дескриптор для LDT 8то1 задачи (селектор LDT). Это поле является статическим. 84
7. При переключении задач не накладывается н и к а к и х ограничений на уровни привилегий старой и новой задачи 1 . Т а к к а к вая задача может быть с уровнем привилегий, о т л и ч н ы м от товня привилегии старой задачи, необходимо иметь указатели ва стеки для всех уровней привилегий. Н а п о м и н а е м , что д л я Ющогоуровня привилегий должен быть свой стек (см. 2.6.3.). )тобы определить необходимость хранения в TSS стеков со всеми I внями привилегий, рассмотрим возможные ситуации. Теку.даетек, т.е. стек для уровня привилегий новой задачи, задается - Естрами SS.ESP, которые безусловно расположены в TSS. Сте•идругих уровней потребуются, если в новой задаче необходимо • |ет вызвать функцию через шлюз. В этом случае потребуется списывание параметров из одного стека в другой. Через шлюз I жно вызвать только функцию с уровнем привилегии численно »«ьшим, чем текущий (см. 2.6.3.). Таким образом, через ш л ю з иожно вызвать функции 0, 1 и 2 уровней п р и в и л е г и й . Вызов ^увкций 3 уровня привилегий через шлюз не имеет смысла. Вот •пну в TSS хранятся только указатели на стеки привилегированных уровней О, 1 и 2 (ESP0:SS0, ESP1:SS1, ESP2:SS2). Ф р е й -
мы стеков определяются на этапе создания задач, поэтому эти п ш являются статическими. 8. Для старой задачи может выполняться отладка в тот мо, когда она прервана. В этом случае после возобновления этой щчи должен быть включен режим отладки. Р е ж и м отладки Сеятифицируется специальным флагом в TSS. Это поле является •анемическим. 9. Если включена страничная адресация, необходимо указать место положения каталога страниц д л я задачи. Адрес нала каталога страниц находится в управляющем регистре CR3, квтому содержимое регистра сохраняется (см. 6.2.2.). Каталог "раниц создается на этапе создания задачи, поле статическое. 10. Известно, что для непосредственной работы с внешними тройствами используются так называемые порты, т.е. адреса, «резервированные за этими устройствами. Например, при рамке клавиатурой на физическом уровне используются порты | вояерами 60Н, 61Н, 64Н. Непосредственный доступ к порш может быть запрещен для программ с уровнем привилегии ' ~ ы образом, механизм переключения задач можно использовать для пере'и .шя между режимом ядра и пользовательским режимом в обоих направлена.
85
численно выше О. Напоминаем (сл. 2.2.3), что максимальное» ченне уровня привилегии, для которого разрешены эти опери» можно прочитать в битах IOPL регистра флагов (биты 12, 1 Установка этих битов разрешается только программе 0 ура привилегии, т.е. ядру ОС1. Это еще одна степень эпщиты.ютч может быть использована ОС для обеспечения невозможна работы с устройствами ввода-вывода напрямую в преломи пользователя (см. 2.2.3). В операционных системах WINDOW 9Х эта возможность не используется, в данных битах устввя» но число 3. В ОС WINDOWS 2000 и выше в этих битах 3i число 0. Процессор позволяет для отдельных задач опр номера портов, с которыми данной задаче разрешается р напрямую. Это позволяет гибко изменять права для отделила» дач. Для задания этой информации используется карта БЕДОВ вода. Эта карта является частью TSS (статическая ипф Кроме самой карты, в TSS задается смещение для начала STOJщ ты относительно начала TSS. Если значение смещения совщ с размером TSS. это означает, что карта ввода-вывода отсутпце Размер карты определяется разностью размера TSS л cweoai карты ввода-вывода. В карте один бит соответствует одному п ту. Так как номер порта задается 1б-битным числом, мякиши ный размер карты равен 2 16 битов, или 2 1 3 = 8 Кбайт. Битс • ^ ром 0 соответствует порту О, бит с номером 1 порту 1 и т д £•! бит карты равен 0, доступ к соответствующему порту раз Для запрещения работы с портом необходимо соответст бит карты установить в I. Таким образом, для разрешения равя со всеми портами необходимо в конце TSS задать 8 Кбайт ву; данных, в поле смещения указать смещение для этой облася» носительно начала данных; при задании размере ТЗБучет, Щ карта должна быть внутри TSS. Заметим, что не обязательно ц ввода-вывода должна иметь размер 8 Кбайт, он может быть ш ше, если разрешение требуется не для всех портов. Размер*»* в завнсимости от максимального номеря порта Nm„ длякотфп необходимо разрешение, определяется по формуле: Размер карты •= (Nmx + 31)/8 + 1 (байт). В последнем байте должно быть задано 0FFH-
твыиилци-п, т о л ь к о кол с уровнем привилегий. 86
Пример. Пусть необходимо разрешить работу с портами Mi 61Н, 64Н. В этом случае Nm31l = 64Н, или 100. Используя л-iy (3.1), получаем Размер карты = 1 7 ( б а й т ) .
Карта разрешения ввода-вывода: DD
3 dup (OFFFFFFFFH )
DB
11101100В, 3 DUP (OFFH)
DB OFFH
Первая команда (DD 3 dup (OFFFFFFFFH)) определяет, что ti&Ti с портами с номерами 0..5FH заблокирована. Первый байт команды разрешает работу с портами с номерами 60Н, 1H,64H(CJK. начиная с младшего бита), все остальные биты этого %1гзиЗ последующие байта блокируют соответствующие порты. О* дний байт указывает, что карта завершена, т.е. все осталь01- порты заблокированы. Таким образом, размер TSS может изменяться для различал -сдач. Кроме карты ввода-вывода, операционная система > • хранить в TSS дополнительную информацию, которая моir'virb записана перед картой. Минимальный размер TSS равен 15! Мйтам, т.е. при переключении задач необходимо сохранить и •те восстановить, по меньшей мере, 104 байта. Поэтому операЯ> ]ереключения задач является вычислительно сложной. Пере<;> евие между задачами происходит, если: 1 В командах call, jmp задан селектор для TSS и л и селектор шлюза TSS — явное переключение. 2. Выполняется переход на обработчик прерываний и л и исL& ении — неявное переключение. 3.Выполняется команда ireti после завершения задачи, вы»"топ командой call (т.е. установлен флаг вложенности задач TBEFLAGS).
Заметим, что задача не может быть рекурсивной, то есть м- я из задачи переключиться на нее же. 3.2.3. Дескриптор TSS
Сегмент состояния задачи, к а к и все п р о ч и е с е г м е н т ы , чяется дескриптором. Дескрипторы д л я всех TSS задач я в GDT. Дескриптор TSS я в л я е т с я примером системного ' и шгоде из вложенной задачи вместо команды RET используется команда ЧI i торая восстанавливает содержимое регистра флагов EFLA GS. В этом слу• • миле СД1Х для вызова задачи должна предшествовать команда PUSHFD.
87
дескриптора. Миинмальпый размер TSS прп условна отсу*шг карты разрешения ввода и вывода н дополнительной инфарниш равен 104 байта. Если предел сегмента меньше 103, то при • т ключекни на такую задачу генерируется исключение. Для защиты от рекурсивного вызова задачи дескрняг1 содержит битовое поле занятости (Busy — В), которое устий лнвается в 1, если задача исполняется или находится в режа ожидания. Любой программный код с текущим уровнем црипш гни, равным или выше DPL, для TSS может переключить задм. Для централизованного управления задачами рекомендуете! » бирать DPL — 0, в этом случае только код на 0 уровне при** •-«*< сможет выполнять переключение. Заметим, что сегмент TSS является особым по правам =*"> па. Право чтения-записи в этот сегмент имеет только проц* • Пользователю с любым уровнем привилегий в этот сегмеп» только нельзя записать какую-либо информацию, во даже «ф читать. Для выполнения таких команд необходимо фактнч»» задать два сегмента: один TSS, другой — обычный сегментм пых с тем же адресом, что и TSS, и той же длиной. В атомедуа если необходимо читать пли писать в этот сегмент, нсволию! сегмент данных, при необходимости переключения задается ?$ 3.2.4. Регистр задачи Регистр задачи {Task Register — TR) содержит пнфор-1 о текущей исполняемой задаче. Содержит «видимую» в «я J~ мую» части. «Видимая» часть может считываться и mvear*-программным обеспечением. «Невидимая» часть недель, процессором. Видимая часть содержит селектор для TSS | держащий индекс TSS в GDT. Процессор использует иеввьщ! часть для записи адреса начала и предела дескриптора TSIi. нение в регистре этих значений делает выполнение задачу эффективным, поскольку для ссылки к TSS текущей задачи у цессору не требуется извлекать эти значения из памяти. Для работы с TR используются команды LTR н STR, • ветственно, для загрузки в регистр и чтения содержимого ре стра задачи. Селектор в GDT задается 16-битным чпглом. ITtje команда является привилегированной в выполняется ОС и инициализации первой задачи. Последующие загрузки ре г-) задач выполняются неявно при переключении задач. К -••» STR не является привилегированной командой, ее можно Wrj* 68
вать для получения информации о текущей задаче. Операндом шаяды является 16 битный регистр общего н а з н а ч е н и я и л и с] памяти типа WORD. Пример 1. Написать команды для записи в регистр задач ;ектора для TSS, если известно, что дескриптор для TSS задан >3 строке. Mov eax, 3' 8; Смещение в таблице дескрипторов LTR ах: младшие 3 бита равны 0, т.е. PL = О; GDT
Пример 2. Определить место в таблице глобальных дескрипт^ров для TSS текущей задачи: STReax В регистре БАХ получим смещение TSS в GDT. 3.2.5. Шлюз задачи
Используется для защищенного п е р е к л ю ч е н и я м е ж д у заитами. В шлюзе задается информация о TSS, поэтому переклюtr-jne между задачами выполняется косвенное, т.е. в команде -рехода задается шлюз задачи, в котором находится адрес TSS. JLTJOJ, В отличие от TSS, может быть определен не только в G D T , П и в LDT. Уровень привилегии ш л ю з а , по сути, определяет нь привилегии задачи, которая может переключиться на за1 I, определяемую шлюзом. Так к а к шлюз рассматривается к а к гмент данных старой задачи, то его уровень привилегии должен численно больше или равным текущему уровню привилегии н^ой задачи. Использование шлюзов позволяет иметь несколько и.тюзов для одного и того же TSS, к а ж д ы й шлюз соответствует г чу уровню привилегий. Это позволяет контролировать доступ ш ОС в пользовательском режиме. Обычно уровень приигегтт для TSS равен 0, и прямой доступ к TSS допустим только и:.1чам ОС; через шлюз, подготовленный ОС, можно получить юли к этим задачам любому приложению. 3.2.6. NT флаг в регистре EFLAGS
Вы те знаете, что переключение между задачами возможно вуня способами: по команде JMP без возврата в старую задачу и s I шнде CALL с возвратом. Рассмотрим, к а к и м образом выпол•яетса возврат в старую задачу во втором случае. В этом режиме в поле связи TSS записывается селектор для :гарон задачи, поэтому процессор «знает», где находится TSS 89
для этой задачи (TSS всегда определен в GDT, а смещение • таблице определено в поле связи). В регистре флагов исполню^ задачи устанавливается бит NT, что означает, что по aaeepj*» этой задачи необходимо вернуться н старой задаче. Таким зом, бит NT задает необходимость вернуться, а поле связи • вернуться. Так как рекурсивный вызов задачи невозможен, Щ возврата всегда один и тот же. 3.2.7. Алгоритм аппаратного переключения между задачами Алгоритм включает в себя следующие пункты. 1. Из операнда команды JMP или CALL процессор по. с е л е к т о р , у к а з ы в а ю щ и й н а T S S ИЛИ ШЛЮЗ T S S -
2. Процессор проверяет, достаточно ЛИ ПОЛНОМОЧНА задачи для переключения задач (ее текущий уровевь ери »*» и RPL новой задачи численно не больше DPL для TSS или ая TSS, соответственно). В случае переключения между задачей. команде /RET уровни привилегий для старой и новой задач et > веряются. 3. Процессор проверяет, присутствует ли в памяти Т&.» вой задачи и не меньше ли его размер минимально допу (предел не меньше 103). 4. Процессор проверяет доступность новой задачи (од. < должна быть занята, т.е. флаг BUSY в дескрипторе TSS аш быть сброшен). 5. Если для переключения задач используется команд! флаг BUSY для старой задачи сбрасывается. Если пепомр ся команда IRET. флаг BUSY сбрасывается в копий реп -» EFLAG.
6. Выбирается адрес TSS для текущей (старой) задачи i гистра задачи и туда сохраняются все динамические поля, г I числе содержимое регистра EIP, который определяет адрес ф редной команды в прерванной задаче. 7. Если для переключения задач используется команда Ж в обраее регистра EFLAGS в стене устанавливается флаг ности задач (NT). Если используется команда IRET, флвгМГ« разе регистра EFLAGS в стеке сбрасывается. 8. Для новой задачи, которая инициирована комшш CALL, JMP, устанавливается флаг занятости BUSY в дескре-» TSS этой задачи. 90
9. Устанавливается флаг TS в образе регистра CRO в TSS этой га. Бит IS полезен системным программам для координации |Л|'Ы целочисленного блока и блока операций с п л а в а ю щ е й twra. Бит TS указывает на то, что содержимое блока операций -авающей точкой может отличаться от соответствующего соЦпмого для текущей задачи. 10. Загружается регистр задач TR, который теперь должен азывать на TSS новой задачи. 11. Загружаются все регистры из TSS этой задачи, в том чяс•т CR3, благодаря чему будет использовано виртуальное адресное Ш фавство новой задачи, EIP, т.е. следующей будет выполнена пшшда новой задачи. Еслп при выполнении какого-то пункта алгоритма произо. ошибка, алгоритм завершается. Обратите внимание на пункты алгоритма, связанные с прор. юй уровней привилегий. Как видно из их анализа, учитываг япривнлегии TSS и шлюзов, но не сегментов команд и данных ; >гаяемых задач. Таким образом, ОС может полностью взять юбя управление переключением, устанавливая в 0 дескриптор1 -и уровень привилегии TSS. В заключение рассмотрим зависимость значений различных V-JOB и полей при выполнении переключений между задачами шли способами. Здесь приведена таблица, которую необходиг даолнить самостоятельно. Дтя сравнения вашего ответа с правильным смотри Прило•яие1. Таблица
3.1
Состояния флагов, используемых для переключения задач J
Команда JMP
Флаг или поле •;аг занятости (Busy) для новой задачи Фм занятости (Busy) для старой задачи ;ж вложенности (NT) для новой задачи * |г вложенности (NT) для старой задачи Па к связи (Link) для новой задачи II -связи (Link) для старой задачи •1>!>гпереключенпя задачи (TS) ктрeCRO
91
Команда CALL
Команда 1RET
3.2.8. Многозадачный режим для многопроцессорной системы В настоящее время большое распространение погт»в1 многопроцессорные системы. Требования эффективной пщ ки многопроцессорного режима является одним из важных I современных ОС. Рассмотрим алпаретнуто поддержку aroi бования. Предположим, что все процессоры, включенныевп» му, являются одинаковыми. Такие многопроцессорные састав называются симметричными. Наряду с такими процесс! в системе используются специализированные процессоры, и мер, графические, видео, для обеспечения связи и др. Все эти яр цессоры используют одну общую системную шину. Основные трудности, которые необходимо преодолеть в я ном случае, — это синхронизация работы процессоров в 'Ail чение высокопроизводительного доступа к памяти. Задач- л хронивации возникает, например, если два или более проце одновременно пытаются получить доступ к одной ячейке паи Задача высокопроизводительного доступа к памяти реши ч с помощью кэша, но в этом случае один процессор можя ' щаться к данным, которые находятся в кэш-памяти друг» а цессора, в этом случае возникает проблема доступа кдостомри данным. Ниже будут рассмотрены некоторые механизмы решен этих проблем. Использопоние атомарных операций
Атомарная операция — зто операция доступа к памят* ние или запись), которая, будучи начата на одном процессор».i может быть прервана до ее завершения. Это обеспечивает гщл тированное ва вершение операции доступа к памяти одни» <| цессором до начала операции доступа к этой же памяти процессором. К таким операциям относятся операции чтепыш ваписи байта, 2- и 4-байтовых слов при условии, чтооии ны на свою границу, т.е. их адрес делится на длину блока япа Для Р6 процессора гарантирован атомарный доступ для что ИЛИ ваписи к выровненному данному длиной 8 байт, в тнюя i ступ к данным из кэш-памяти длиной 1, 2, 4 и 8 байтов, если» находятся внутри одного элемента кэш памяти. Для данных, пересекающих границы элемента каши страницы, атомарный доступ не гарантируется. Таким следует уделять внимание выравниванию данных не только 92
I
•
»тичения производительности, но и для обеспечения корректri работы в случае использования многопроцессорных систем. Атомарный доступ не гарантируется для операций чтения и жгг, например, в команде ADD [х], 1 требуется доступ к облает самяти х для чтения и записи. В этом случае один процессор ш*. прочитать значение х, затем второй процессор читает то же 1 чение X, увеличивает его на 1. Когда первый процессор проgxt вт операцию, он увеличивает на 1 предыдущее значение х. fccie выполнения обеих операций значение х изменится не на 2, ш «вдается, а на 1. Для предупреждения т а к и х ошибок досту:. ц;-ользуется блокирование команд. Использование префикса
LOCK
При выполнении некоторых сложных команд процессор ав• м;ически формирует сигнал LOCK, который обеспечивает выЯлевие операций без прерывания до их завершения. Примеры ШпЬ операций: - XCHG при обращении к памяти; установка флага занятости в дескрипторе TSS; - модификация байта доступа в дескрипторе. Программист может использовать префикс LOCK перед ко|а:»мп пересылки, арифметическими командами, командами ;м работы с битами, в которых выполняются чтение и запись ишть; в этом случае операции не могут быть прерваны. Если данные находятся во внутреннем кэше процессора, до<тч»-рвость данных для других процессоров обеспечивается на сиратном уровне, начиная с процессора Р6. Команды сериапизации
Из первой части курса известно, что одним из средств уве• «ш скорости работы процессора или повышения тактовой и тоты является увеличение числа элементов конвейера д л я «мнения команд. К моменту завершения очередной комани следующие команды готовятся к выполнению. Команда напвается командой сериализации, если перед ее выполнением дотируется выполнение всех команд, которые до нее находись в конвейере, в том числе запись в память данных из кэша. Т.е. теперь выполняется не сброс конвейера, к а к в случае команд »«хода, а выполнение всех операций для всех команд, д л я котовыполнение у ж е н а ч а т о .
Примеры команд этого типа. 93
Пример 1. Команды записи в управляющие пли о т л д а а регистры. Так, команда MOV СR0, ЕАХ является коыавдо! nj» ализации. благодаря атому при переключении в защнщенаы! • жим после этой команды не требуется команда перехода, т ^ ш ранее использовалась для сброса конвейера. Пример 2. Команды загрузки дескрипторвых репеЯ и регистра задачи, например, LTR. Пример 3. Команда СPUID. Использование команд сериализации позволяет всклш необходимость команд безусловного перехода после перил ния режимов работы процессора, в том числе, включения ф ничной адресации. Рассмотренная вьтхе аппаратная поддержка много задаче режима обеспечивает возможность безопасного доступа к J4 памяти в одно- и многопроцессорном режиме в условиях о. аф менного выполнения нескольких задач. Она также обеспечив сохранение текущего состояния задачи, переключение нехц » дачами с последующим восстановлением состояния прервши задачи. Но на этом уровне не могут быть решевы некоторые^ блемы, например: — выбора новой задачи из множества готовых задач, — одновременного доступа к области памяти размером чж одного байта; — выделения оперативной памяти, если много задач • т рируют между собой. Эта задачи решаются ОС- Напоминаем, что для задач*» работчики ОС используют термин «Процесс».
3.3. Состояние и д и а г р а м м ы состояний для процессов 3.3.1. Состояния процессов. Переключение состояний Как уже определено выше, единицей работы, которойутц» ляет ОС, называют процесс. С точки зрения программисте, * цесс — это программа при исполнении- Назовем жнзиепи циклом процесса время м е ж д у созданием процесса н его -ь чтожением. В течение жизненного цикла процессы могут бив в различных состояниях: — пассивное состояние. Программа в памяти, но не row к исполнению; 94
-готовность. Процесс готов к в ы п о л н е н и ю и ж д е т к в а н т а ш процессора; - выполнение. Процессу выделен к в а н т времени централь•усцессора; ожидание. Выполнение процесса прервано в с в я з и с о ж и I, »ч необходимого ему ресурса, например, о к о н ч а н и я операIB/с да данных или завершения в ы п о л н е н и я другого процесса, г ый готовит данные для чтения первым процессом. Диаграмма состояний в наглядном виде представляет переюь « одного состояния в другое. Пример д и а г р а м м ы состояний кишлев на рис. 3.2. Г товые процессы переходят в состояние в ы п о л н е н и я с повши. ' -ужб планирования и диспетчеризации, к о т о р ы е распре»j.nr процессорное время. Эти же с л у ж б ы переводят процесс I» шие готовности по истечении кванта времени. Ели исполняемый процесс запросил ресурс ввода-вывода, то а •'«водится в состояние ожидания и находится в этом состо№ у завершения запрошенной операции. В это в р е м я потоку ®~тсвремени не выделяются. После з а в е р ш е н и я этой о п е р а ц и и переходит в состояние Готов, если м о ж е т б ы т ь продол-чи в пассивное состояние, если п р и в ы п о л н е н и и операции •л вывода обнаружена ошибка. В пассивное состояние процесс фидат из состояния выполнения при з а в е р ш е н и и процесса. Xv " ивного в состояние готовности происходит переход п р и • «взации приложения (повторном его запуске).
Рис. 3.2. Состояния процесса
Эффективность ОС может Быть оценена Do распредели процессов по различным состояниям. Если большинство «я сов находятся в состоянии ожидания ввода-вьшодв, то ич ограничена по вводу-выводу; если большинство процессов*** ивают в связи с ожиданием процессора, то система о .« иМ быстродействию и т.д. 3.3.2. Абстрактное определение процесса Пусть X = {jcO, .rl, ...} набор переменных (может бьп, | конечный), характеризующих состояние процесса (нвб% 1 мвнвых состояния). Для программы — это переменные, -А лающие исходные данные, конечные данные и пром( переменные. Состояние определяется конкретными значениям! Й переменных после выполнения конкретного оператора. Пространство состояний — для данного набора перем> состояния это множество состояний, которые могут я ••« вти переменные. Действие — присваивание значений некоторым из и Ж ных состояния. Для программы это оператор, который «•« ет значения некоторых переменных. Каждое действие (оператор программы) переводит fM в новое состояние, последовательность состояний — это. •»> Функция действия — функция, которая опредет». надо сделать с текущим состоянием, чтобы перейти всд-лв состояние. Функция действия является не чем иным, как « тором. Последовательность исполняемых операторов н ~i программу. В этом случае процесс можно определить как п. • состояний, начальные состояния, функции действия. Пример. Пусть программа вычисляет НОД (дт, у). while (х && у){ if (х < у) у%-х, else х%=у.
}
if(x) res = х,- else res = у:
Определим пространство состояний, начальвые состоя» и функции действия для х = 24; у = 36. Начальное состояние х 24; у 36. Ответ пока ней» Таким образом, начальное состояние может быть пред И вектором (24, 36, ?}. 9(5
Промежуточные с о с т о я н и я :
[24. 12, ?}, 12, ?}. Отечное состояние:
О, 12, 12}. Функции состояний:
у % = х ; х%=у; res = fx = = 0 ? у: x j .
В рпльных задачах множество состояний может быть очень , в этом случае можно рассматривать только их подмно|- , вапример, если есть вызов функции, то в подмножество я0| ве включать промежуточные результаты, которые получавп жутри функций. ! я независимых процессов пространства состояний не загг друг от друга, т.е. каждый процесс имеет отдельный набор «рясввых, для взаимодействующих процессов д о л ж н ы испольwr-.'я разделяемые переменные. В реальной ОС ф у н к ц и и дей® и - это функции ОС, а переменные состояния — содержимое ©(j"энныхобластей памяти, устройств вывода-вывода и др. Состоянием процесса можно связать число (текущее значет.-^меви. когда это состояние началось). Такое состояние нал - гея событием. События позволяют отследить изменение сот-ля процесса. Начало и конец каждого действия отмечаются d-.иями, которые обозначим, соответственно, для действия а: riity.KOH (а). Если для всех действий процесса аО, а1, ... (at) .НАЧ (ai+1), такой процесс называется последовательи>. В любом случае процесс можно определить к а к последовал вость событий НА'Ч (аО), КОН (аО), НАЧ (а1), КОН (а1) bus последовательность называется следом процесса. мпекстом процесса называют информацию, которую дей•|ипроцесса могут изменять или проверять. Он включает в себя адгощую информацию: - контекст процессора (все регистры); контекст памяти (для определения адресного простран-!> процесса); -атрибуты процессора (имя, приоритет, права, которые исBi зуются для определения, какие операции разрешены); -список используемых ресурсов. С'ед процесса задает последовательность состояний контекста. Формальное определение процесса позволяет формализовать о.? тение отдельных функций ОС, точно так ж е , к а к аналитищ, к методы доказательства правильности программ позволяют П7
выполнить это доказательство, но только для простых про Ввиду сложности ОС для определения всей ОС эти метод ч не используются. Реально они могут использоваться т- • • . экзоядра ОС (СЛ. 2.2.3). 3.3.3. Отношения между процессами До сих пор считалось, что одновременно выполняете! тп ко одни процесс. Теперь рассмотрим выполнение совоцма процессов. В этом случае должны определяться начало • MI каждого действия для всех процессов. Контексты процесса Л иметь общие части. Если контексты процессов не пересе'•"» они называются независимыми, если какая-то часть ког— используется только одним процессом, она называется co&q ным контекстом. Примером пересекающихся контекстов Ш ся использование общей функции иа DLL. Данные, испозычМ DLL, являются собственными контекстами. Таким образом, процесс можно определить как совакуия всех его состояний (аналог табличного задания функции! ш« чальным состоянием и функцией перехода в конечное с е т (аналог аналитического задания функции). Так как процяг* жет быть прерван в любое врамя, для него запоминается щ жуточное состояние. ОС необходимо задавать состояние пряш в компактном и удобном для использования виде. Эффекi 1 ОС в большой степени зависит от структуры данных дляспре~ ния процессов п методов доступа к этим данным. 3.3.4. Классификация процессов В зависимости от функций н режима процессора, в МЩ выполняются процессы, они делятся на системные н п— вательские. Процессы ОС называют системными вроцкЛ в отличие от пользовательских процессов. Наряду с свстех^} и пользовательскими процессами в некоторых ОС нспсжЩ ся процессы-демоны (UNIX). Процесс-демон — рпзпсвядв»" системного процесса. Эти процессы отличаются от обычыц стемных тем, что выполняют специфические системные ции. Примерами таких процессов являются процессы, «09 обрабатывают нее вапросы на соединение в сети или проста» которые выполняются периодически или в заданный времени.
3.4. Структуры, используемые для з а д а н и я процессов зависят от конкретных ОС, но д л я б о л ь ш и н с т в а ОС э т и 7 -лрыаналогичны. Щ ^м называть информационную структуру д л я процесса гч'мтором процесса. Множество дескрипторов образуют та_ir процессов. J я ОС, которая базируется на процессах, дескриптор про:«(|1включает в себя следующую информацию: - идентификатор процесса; ивформация о запустившем его пользователе; - текущее состояние процесса (готов к работе, работает, заЬсрован, пассивное состояние); - контекст процесса — область п а м я т и д л я записи информапроцессе при его прерывании. Эта область п а м я т и д о л ж н а ушить все компоненты, которые позволят п р о д о л ж и т ь выпол40» прерванного процесса. Зависит от к о н к р е т н о й архитектуЬа процессора типа 1-32 это TSS; - информация о ресурсах, которыми владеет процесс. 3.4.1. Структура дескриптора процесса для ОС LINUX
Дескриптор включает в себя следующие п о л я . Состояние процесса. Набор битовых флагов. Одновременно ««ет быть установлен только один флаг. П р и м е р ы состояния: JBCC выполняется или ждет исполнения (готов к работе), проsзаблокирован до выполнения определенного события и т.д. Идентификатор процесса. Каждому процессу присваиваетз тгашышй идентификатор. Все потоки процесса имеют один I тот же идентификатор процесса. Они заносятся в список, верina которого и есть идентификатор процесса. Т а к и м образом, юидентификатору процесса можно определить и д е н т и ф и к а т о р ы потоков этого процесса. Список ц и к л и ч е с к и й , двухнаправ.ггньш. Это обеспечивает возможность легкого определения конj списка и просмотра списка в обоих н а п р а в л е н и я х . З а м е т и м , т>иневно такого рода списки используются ОС L I N U X наиболее чего. Для эффективного определения дескриптора процесса по его идентификатору используются хеш-таблицы. В наиболее прогчж случае идентификатор — это индекс дескриптора в таблице вгхрипторов, чаще используются более с л о ж н ы е ф у н к ц и и д л я 99
вычисления дескриптора по хеш-таблице. Так, дая ccptj-ти» номера строки в таблице дескрипторов DO идентифти-** ОС LINUX использует макрос: «define pict_hasbfn(x) ((((х) » 8)
Л
(х)) & (PIDHASH_SZ— 1
В этом макросе PIDHASH SZ — число строк в та скрипторов. Рассмотрите этот макрос для количества стрж->» лице дескрипторов 32768 (2 15 ). Определите, в каком ci •« ступают коллизии. Кстати, дли процессов с одинаковыми v строки в хеш-таблице формируется список. Количество « в атом списке равно числу дескрипторов процессов, коготь* » ют один и тот же ключ в таблице. Указатели для определения родительских итношенЛ4 ду процессами. Н и ж е представлены основные из них: - указатель на процесс родителя, благодаря которо! но для любого процесса-потомка найти всех его предков, в-.--м процесса init, не имеющего родителя; — указатель на процесс родителя, которому надо тж» лиаировать о завершении процесса-потомка, обычно соя-иг с предыдущим; — - указатель на самый последний процесс в цепочке. зуется, если надо добавить процесс в конец цепочки, ие » •-« каждый раз всю цепочку процессов; — указатель ни следующий элемент в цепочке, нсп ся, если надо пройти цепочку сверху вниз, просматривая цессы. Ресурсы, выделенные процессу. К ресурсам отвоеятм •»» щий каталог, переменные окружения, открытые файлы. • ленные области памяти. Память для сохранения аппаратного контекста. Д.11 цессоров, совместимых с 1-32, в качестве контекста ксп( 1Щ ся TSS, рассмотренный в 3.2.2. Заметим, что многие ОС, * ч» числе современные системы LINUX, не используют агпар««й переключения задач по двум причинам. Первая - передние выполняется медленно, так как требует обязательного ключения в режим супервизоре. Вторая причина ищи переключение за счет необходимости копирования все* TSS, большая часть которых постоянная. Так как переключу процессов выполняется достаточно часто, то важно минпш вать число байтов, которые необходимо сохранить и восстань: при переключении. Поэтому программное переключение «Я 100
m i > выполнено быстрее, чем аппаратное. В этом с л у ч а е к о н т е к с т - . . ' И Т только переменные п о л я TSS, т.е. р е г и с т р ы . Но пере.хчение между процессами у ж е не м о ж е т быть выполнено ко«•^иmJMP, Call, как в случае аппаратного п е р е к л ю ч е н и я . Е с л и /шолняет переключение процессов т о л ь к о в р е ж и м е я д р а , то •".•^кимое регистров для пользовательских процессов д о л ж н о мть сохранено до переключения. Для обеспечения более э ф ф е к т и в н о г о у п р а в л е н и я м н о ж е -юмпроцессов ОС образует отдельные с п и с к и процессов, находился в одном и том же состоянии, н а п р и м е р , отдельно х р а н и т с я —1к готовых процессов. К а ж д ы й список содержит у к а з а т е л и в ггскрипторы процессов. Первым элементом с п и с к а я в л я е т с я j| "есе. не имеющий родителя, в поле у к а з а т е л я на п р е д ы д у щ и й >•' • ентдля этого процесса записывается последний элемент спил, таким образом, список является к о л ь ц е в ы м . В этом случае ,1я просмотра всех элементов с п и с к а достаточно использовать игровой цикла lor(p = &init_task; (р = p->next_task) .'= &init_task;), iHoropoM: initjask — голова списка; nextjask — указатель на адрес очередного элемента в списке.
Заметим, что просмотр списка в обратном н а п р а в л е н и и л е г к о ршзуется за счет доступа к последнему элементу с п и с к а и двухы.равленности списка. Легко вставить д е с к р и п т о р процесса, к а к Iначало, так и в конец такого списка, у д а л и т ь процесс из списка, правила, по которым процессы, готовые к в ы п о л н е н и ю , заносятнв список, определяются алгоритмами диспетчеризации и будут усмотрены ниже. Особое значение имеет список процессов, к о т о р ы е ж д у т нагиления одного или нескольких событий, н а п р и м е р , завершения операции ввода-вывода, з а в е р ш е н и я к в а н т а в р е м е н и и др. W 1 список формируется в виде очереди д л я данного события. Ели событие наступает, то из очереди и з в л е к а ю т с я один и л и несколько процессов, которые о ж и д а л и д а н н о е событие. Один ггроцесс извлекается, если используется р е ж и м э к с к л ю з и в н о г о г " ; па, при котором только один процесс м о ж е т работать с данаыы ресурсом. К таким ресурсам относится, н а п р и м е р , клавиатура. Режим доступа процесса к ресурсу отмечается с п е ц и а л ь н ы м ::агом. Режим доступа к файлу определяется п р и создании этого фага. Так, если задан флаг FILE_SHARE_READ, то допускается 101
множественный доступ в режиме чтения и эксклюзивный лил в режиме записи. Для каждого процесса ОС может определять предельные» чения для используемых ресурсов, например: ограничивается максимальный размер памяти, котсрй может использовать процесс, в том числе динамическое иамга (кучи), стека, несбрасывяемой памяти; — ограничивается максимальное время процессоре для в^ цесса, что исключает возможность зацикливания, таккакс(?«а формируемый ОС при достижении заданного предела, о т ш и вает процесс; — ограничивается максимальный размер файла и коп» ство одновременно открытых файлов; ограничивается количество процессов, которое *o«H быть создано пользовательским процессом. Таким образом, дескриптор текущего процесса с i . s j l полную информацию о процессе, и для получения адреса вгаж дескриптора необходимо иметь простой способ. Постоянное : иение этого адреса в фиксированном регистре исключено»run с небольшим количеством регистров. В LINUX эта проблей» шена так. Для хранения текущего дескриптора процесса ист . ядра для этого процесса используется область памяти размера 4 Кбайта (страница), адрес которой делится на 2 14 . Дескряи^ процесса занимает младшие адреса, стек — старшие адреса » ницы. Так как адрес текущей вершины стека всегда i p t m в регистре ESP, то для получения адреса дескриптора текуч» > процесса достаточно вычислить ESP & 0x4000 (Почему?). Эж простой способ определения адреса дескриптора накладе» ограничение на размер стека ядра. Этот стек вместе с деекрп~ ром не может превосходить резмера страницы. 3.4.2. Особенности определения процессов для WINDOWS Каждому процессу соответствует блок EPROCESS, котфй включает в себя полную информацию о процессе. Этот блок ш чает в себя все множество атрибутов, характеризующих срац* и указатели на другие структуры £141- Примером структур затели которых заданы, являются структуры для всех поте» созданных процессом, и исполняемых внутри него потоков.Ъв 102
• включает в себя данные, которые хранятся в области ядра, деые пользовательского режима. В р е ж и м е ядра х р а н я т с я плески те же данные, что входят в структуру дескриптора ЯЖт, описанную выше. В режиме пользователя х р а н я т с я г;. »енвые окружения, которые могут модифицироваться польисгьским приложением. 1дной из основных подсистем ОС WINDOWS является под«пи управления
процессами
(Client/Server Run-Time
Subsys-
m-csrss), которая обеспечивает: -управление окнами; создание и уничтожение процессов и потоков; - поддержку DOS режима; -поддержку создания многоязыковых приложений и т.д. "ha подсистема имеет свою структуру данных для процессов.
3.5. Переключение контекстов Ниже будет рассмотрен механизм определения, когда и каког гоцессу выделять время процессора, а сейчас мы рассмотрим, л выполняете я это переключение. При аппаратном переключении достаточно п о д г о т о в и т ь находимые структуры, рассмотренные выше, и использовать »i:,ao команды JMP, CALL для переключения процессов. При if таммяом переключении необходимо выполнить программно -гонение необходимой информации для обеспечения возможг га продолжения работы старого процесса и создать условия выполнения нового процесса, начиная с требуемой команды. Рассмотрим пример команд для программного переключет, используемого в LINUX1. и хранение дескрипторов старого и нового процессов •г, prev,%eax ml next.%edx г угя копия адреса дескриптора старого процесса
•vvl
%eax,%ebx
' Япмвааех, что в LINUX при записи ассемблерного кода результат помещается втфону адресу. Перед регистром записывается символ %.
103
; Сохранение регистров, которые могут использоваться для служебных целей в стеке старого процессе pushl %esi; Регистровые переменные
pushl %edi pushl %ebp:
Используется при передаче параметров
; Сохранение текущего указателя стека ядре старого провеса дескрипторе со смещением 616. по этому смещению в дескрипторе находится значение у к а з а т е л я с в о е г о стеке ядре movl %esp. 616(%еах) ; Восстановпенив текущего указателя с т е к а ядре для нового • мЯ Фактически теперь будем р а б о т а т ь со с т е к о м нового процка movl 616(%edx), %esp Переход на функцию, которая выполняет п ,
процессов ]тр
ewitch_1o
Фупкция switch_to берет параметры из регистре! Г' ЕВХ, а не из стека. Эта функция выполняет следующие действия: • сохраняет и восстанавливает остальные регистры i числе сегментные, отладочные, регистры с плавающей ММХ, если требуется. Необходимость сохранения дпнно"» ч регистров определяется специальными флагами в де • < процесса; • сохраняет и обновляет карты ввода-вывода BTSS. няется, если хотя бы один иэ процессов, участвующий в чении. имеет уникальную карту ввода-вывода 1см. 3.2)-
3 . 6 . О б р а б о т к а п р е р ы в а н и й п р и параллельном исполнении Начальные сведения о прерываниях рассмотрены • 11 Рассмотрим требования к обработчикам прерыванвгй и » полнению в условиях параллельного выполнения процесса» Ь мы уже знаем, прерывания нарушают естественный порядв! полнения команд. Когда поступает запрос на прерывав* 1 должен прекратить выполнение текущей задачи и переняв Щ 104
«.- тую задачу. Для этого необходимо сохранить регистры д л я •рса к старой задаче (регистры EIP, CS, FLAGS) в стеке ядра ейти на обработчик прерывания. Но обработчик прерывания рвется от обычного процесса. Его можно рассматривать к а к раяющее воздействие ядра (kernel control path) на процесс, ай выполнялся, когда пришел запрос на прерывание. В свяI гам переключение контекстов значительно проще в случае риючениямежду обработчиком прерывания и процессом, чем « пае переключения между двумя процессами. Запрос на прерывания может прийти в любое время. Ядро •дополучить этот запрос и обработать его к а к м о ж н о быстрее, г тщ стороны, во время прихода запроса на прерывание, ядро Ш1 быть занято работой, которую нежелательно откладывать, '„зрешения этого противоречия обработчик п р е р ы в а н и я id делится на 2 части. Первая часть (top half) должна быть •лмена немедленно после получения запроса. Вторая часть Кй ш half) может быть выполнена с задержкой. В ядре хранится Ьв[ь, в которую записываются отложенные функции, которые ил. ляются по мере освобождения ядра. Так как одновременно могут поступить несколько запросов и дай то же прерывание, необходимо обеспечить, чтобы об'^-чики прерываний были повторно входимыми ф у н к ц и я м и . Ьа последнее управляющее воздействие прервано, ядро долж• обеспечить возможность продолжения обработки прерванного кдйствия. Хотя ядро может принять новый запрос на прее т е во время выполнения запроса, могут быть критические • " т которые не могут быть прерваны. При выполнении этих гопъов прерывания выключаются (команда CLI д л я процессо•»1-32). Очевидно, что время выполнения таких участков должао 'ль очень коротким, ядро должно большую часть времени Жмняться в режиме, когда прерывания разрешены.
3.7. Проблемы управления о д н о в р е м е н н о исполняемыми процессами Наличие и одновременное исполнение нескольких процессов урождает проблемы, в том числе, взаимное исключение, необ1 димость синхронизации, взаимоблокировку и к о м м у н и к а ц и и жл„у процессами (межпроцессорные соединения). 105
3.7.1. Взаимное исключение Рассмотрим разные схемы взаимодействия двух про д, которые для простоты требуют одинакового времевв >.»» ния (например, 2 экземпляра одного приложения): — процесс р выполняется до конца, затем выполни тт»я цесс д (последовательное выполнение); — процессы р и q делятся на фрагменты, поочередное» няются фрагменты каждого из процессов, причем вы начинается с процессе р (режим квантования — псевдопв «хм вый режим); — процесс д начинает выполняться после начала про-- , но до его завершения (параллельное выполнение процессе^,. Пусть каждый из процессов использует общий pecyf i рым может одновременно обладать только один нз продаж* » пример, изменять значение одной и той же области панятж Т ресурс называется критическим ресурсом, а процессы, кот необходим один и тот же ресурс, находятся в состоянииваавя исключения, т.е. одновременно доступ к этому ресурсу] лучить только один процесс. Д л я однопроцессорных сн тнческим ресурсом является также и процессор. Одним нз методов решения этой проблемы является ь зование виртуальных ресурсов. Каждому критическому рася ставится в соответствие виртуальвый ресурс. Количество »» туальных ресурсов совпадает с числом процессов, которые i временно претендуют на этот ресурс, В этом случае, всеЗгаа выполнения процессов получаются эквивалентными, во з вание виртуальных ресурсов дает возможность только что процесср выполнится раньше, чем процесс q, общее вра№ полнения процессов конечно не одинаково для трех схем £ называть логическим временем время выполнения ОДР on цесса, если у него нет конкурентов. Пусть два процесса изменяют состояние одной и той ж-*» менной, например, оба процесса считают затраты энергии по муле S += где v вычисляется в процессе- Пусть дли вьгие в каждом процессе используется фрагмент программы: ; Вычисление v tnov eax, [s] add eax. [v] tnov [s], BOX
Если первый процесс будет прерван после выполнении команды загрузки, то в регистре вах будет значевие S до м 106
«процесса 2. После выполнения процесса 2 значение s будет •но, но после восстановления еах снова там будет записано t значение s, т.е. результат выполнения обоих процессов тзависеть только от процесса 1, и не зависит от процесса 2. иная ситуация может возникнуть в случае прерывания г re 2 перед командой ADD. Заметим, что прерывание этого ка программы для выполнения других процессов, не связан(I изменением переменной s, не запрещено, насток программы, в котором используется критический к, называется критической секцией (КС). Одновременно нез процессов не могут выполнять КС для одного и того же того ресурса. Ниже рассмотрены способы решения этой проблемы д л я слукпроцессов. Использование общей переменной
Пусть переменная Status, которая определена в области па,. вмстшюй нескольким процессам (см. 6.4.3), задает состояt питической секции (занята, свободна). Вход в критическую >/лю процесса возможен только в том случае, если она сво/* Общая переменная */ int Status = Free;
Процесс Г/ .Me (Status = = Buzy); Misz Вшу;
•отческая секция*/
/'Процесс 2 7 while (Status = = Buzy); Status = Busy; /*Критическая секция */
tutus: Free;
Status = Free;
Нецостатки метода: -операторы while (Status = = Busy) п р о в е р к и с о с т о я н и я к р и -
нкой секции и Status = Busy установки этого состояния должен щлолняться как один оператор; -неопределен порядок выполнения процессов, в реальных часто необходимо зафиксировать этот порядок; -если квант времени выделен процессу, который не может «шнятьсясейчас, процессор выполняет ц и к л о ж и д а н и я вместо '•течения на другой процесс. Первый недостаток устраняется, например, выключением преш на время проверки и установки значения. Современные 107
процессоры т а к ж е имеют в списке команд такие, которые ляют проверять и изменять значение переменной одной НШЙ дой. Способы устранения второго и третьего недостатков pai трены ниже. П о о ч е р е д н о е выполнение к р и т и ч е с к о й секции
Пусть процессы д о л ж н ы выполнять КС, причем первымд жен выполнить КС первый процесс. Определим общую для сопроцессов переменную, куда вначале запишем номер пронег который должен первым выполнить КС. /* Общая переменная */ Into number = 1; /*Процесс 1*/ while (1){
/"Процесс 27 while(1){
while (number = -2); /*Критическая секция */
while (number = =1); /*Критическая секция */
number = 2, /*Продолжение процесса */
number = 1; /*Продолжение процесса' }
}
Недостаток метода. Если процесс 1 выполняется на бг? быстром процессоре, то он не сможет два раза подряд выполт, свою критическую секцию. По-прежнему процессор простаив.' до завершения кванта времени, если КС не может быть вып.нена. Алгоритм Д е к к е р а
Используем 3 общих переменных для процессов: c[0] — № i на, если выполняется КС первого процесса; с[1] — истина, если-, полняется КС второго процесса; переменная OtherProcessNu^t задает номер неактивного процесса. Начальная иницналпзки переменных: bool с[2] = (false, false}; int OtherProcessNumber = 0; /*Код для процесса 1 с критическим участком кода 7 // Установки переменных для первого процесса int i = 0, j= 1 —i; c[i] = true; OtherProcessNumber = j;
108
/ЖЗем, пока критическую секцию выполняет второй процесс Me (c[jl && OtherProcessNumber = =j); Оптическая секция
t;i!-false;
Дтя второго процесса переменная i = 1. Проверьте поведение процессов в случае прерывания после и*. го из операторов до начала КС! Для решения проблемы простоя процессора в случае пеобхо1вгти ожидания завершения выполнения КС другим процесса пользуется блокирование процесса, выполнение которого с кчжет быть продолжено. Блокирование процесса выполняет V В этом случае квант времени процессора передается готовому фггт. В следующих разделах предполагается, что процессы, гп- дае не могут выполняться, блокируются. 3.7.2. Синхронизация
Проблема синхронизации возникает для зависимых процесH. когда выполнение одних процессов зависит от выполнения | сл. Пример 1. Если один процесс пишет запись, а второй ее читадо завершения создания записи читать ее не имеет смысла. Пример 2. Пусть есть N процессов, к а ж д ы й из которых вымнет определенную задачу, например, получает информацию И" гтнчных клиентов. Пусть есть процесс, который выполняет пии тическую обработку этой информации. Последний процесс •нет быть запущен только после получения информации от всех Bit атов. Место в программе, с которого начинается код, выполните которого возможно только после завершения группы про4с os, называется местом встречи. В этом случае процесс состоит I. .лей: Процессi Начало процесса Встреча Продолжение процесса Конец процесса
109
Указанные точки встречи называются точками синхрон • ции. В точке синхронизации процесс должен ждать, покане(выполнено определенное условие. Назовем состояние ожш4 щего процесса блокированным в противоположность активно* состоянию. Д л я реализации синхронизации можно использовать t | тия, для которых определено два состояния (произошло - SA, led и не произошло — unsignaled). Изменение состояния собы а выполняется неделимой (атомарной) командой. Рассмотрим использование события для решения проб.т . записи перед чтением. ClearEvent Процесс Р (Запись) Запись a SetEvent (Event); Продолжение P
(Event) Процесс Q (Чтение Wait (Event); Чтение a
Для второго примера предлагаем такую схему для кажд щ процесса: //Начальная установка, п = 0; ClearEvent(Event); //Для каждого процесса п++; if(n < N) Wait (Event);// Ждем в точке встречи SetEvent (Event);
Предположим, что все процессы, кроме двух, дошли до ки встречи. Рассмотрим функционирование последних двух пр цессов. mov inc стр je ; Wait
еах, [п] еах еах, N т1
m l :
пусть переключение между процессами выполняется п каждой команды. В этом случае д л я каждого процесса в еах пишется значение 7V—2, так к а к N—2 процессов дошли до то и встречи. Предпоследний процесс увеличит значение еахдо.\'-1 переходит в состояние о ж и д а н и я . В этом же состоянии находить процессы, которые выполнялись ранее. Последний процессуы-л чит значение еах до N и разблокирует все процессы. 110
Ьоимоблокировка
Конкуренция из-за права владения ресурсами может прик состоянию взаимной блокировки, при котором каждый урврующих процессов не может продолжить выполнение с тем, что необходимый ресурс занят другим процессом, гбытьивслучае, если два процесса используют ресурсы, иа:димые третьему процессу. Обнаружение и предотвращение блокировок (тупиков). Стратегии решения проблемы
Усмотрим два процесса. Пусть каждый процесс имеет две отие секции, связанные с использованием разных ресурса. пример, файлов. п роцесс 1 Процесс 2 "ачало КС1 Начало КС2 Начало КС2
Начало
Гонец КС2
Конец
КС1
онецКС1
Конец
КС2
КС 1
Пуль все шаги процессов выполняются в таком порядке: Процесс 1. Начало КС1 Процесс 2. Начало КС2
Процесс 1. Начало КС2 Процесс 2. Начало КС1
Заметим, что шаг Процесс 1. Начало КС2 б у д е т з а б л о к и р о -
m "тккак КС2 занята процессом 2. Аналогично, шаг Процесс 2. КС1 для процесса 2 также будет заблокирован. Такая ситуия называется взаимной блокировкой, или тупиком. Замета, что блокировки не возникнет, если критические • > „ н инициализировать в одинаковом порядке! Первая схема предотвращения тупиков основывается на их юсущении. Когда какой-то процесс делает запрос, который мот привести к тупику, система не удовлетворяет этот запрос или яЬрает этот ресурс у другого процесса, чтобы избежать тупика. Рассмотрим несколько способов предотвращения тупиков. 1 способ. Каждый процесс вначале запрашивает все необходим ему ресурсы. Процесс запускается только в том случае, и все необходимые ему ресурсы есть в наличии. В этом случае 111
тупик никогда не возникнет. Недостаток способа — pecyptun выделяться задолго до их использования, что ограничишь- • пользование этих ресурсов другими процессами. 2 способ. Все ресурсы делятся на классы. К классу с W 1пим номером отиосятся наиболее критические ресурсы, f* рые должны выделяться кратковременно. Процессу выд -» ресурс из заданного класса только в том случае, если этот|^ есть в наличии и если процесс освободил все ресурсы с болыя номерами. Это стимулирует быстрое освобождение крит»*и ресурсов процессами. Заметим, что первый способ являетич ным случаем второго для одного класс. 3 способ. Алгоритм аналогичен алгоритму принятие 11 ния по выпуску займа, и поэтому называется «алгоритм"* кира»[8]. Пусть общее количество ресурсов данного тиса СиResourceCount. Пусть на эта ресурсы претендуют N процессов 0.1,2.. • Пусть максимальное количество ресурсов для процесса • ResourcrCounli, MaxResourceCvuni-2. — MaxResourceCou-* ч ответственно, причем MaxResourceCoun 11 + МахНеяоигсгСШ + ... + MaxResourceCounts > CammonResoureeCount. Пусть" щее количество ресурсов, выделенное каждому процесс» и AllocResourceCounto, AtlocResourceCounti, .... AMocft"-Count*г i- Необходимо олределить. можно ли выде-штьаалшч процессу определенное количество устройств. Для грнввтн шения о выделении система проверяет возможность всех уже запущенных процессов при условии, что они uq* все необходимые им устройства. Если какой-либо процесс быть завершен, предполагается, что он освободит все завятш ресурсы. Если все процессы могут быть завершены, охерц порция ресурсов выделяется. Если хотя бы один процессне+« быть благополучно завершен, то ресурс не выделяется. //Начальная
инициализация.
Все ресурсы
свободны
FreeResourceCounl = СommonResourceCount; /I Инициализация. когда часть ресурсов уже выделена I/ (для некоторых процессов возможно, что // AllocResourceCountlil = 0) Н Определим общее количество свободных ресурсов //и ч и с л о ресурсов, которые осталось выделить
Н каждому процессу. 112
Повременная bNotEnd[i] = true, если процесс не завершен. Гак как в начале все процессы не завершены, )№ tEnd[i] = true предполагается, что не закончится из-за нехватки ресурсов kr/i-0:i
I
Принятие решения о безопасности системы. I «Выполняем» те процессы, которые можем. 'Переменная Priznak = истине, если хотя бы один процесс " иожет быть выполнен KOlPrizriak'true; iHMPriznak){ //Выйдем из цикла, если ни одному из процессов не сможем //еыдепить необходимое число ресурсов Priznak = false; fot(i = 0;i
} } i Смогли выполнить есе процессы? п (FreeResourceCount == CommonResourceCount) Система безопасная; else Система не безопасная; 113
115
Но такое решение приводит к тому, что программа обнврц. нин опасных ситуаций может занимать много времевв, так ш* надо выполнять при каждом запросе на ресурсы. Вместо недопущения тупиков можно использовать и томатическое обнаружение и, в случае их наличия, отбхрг ресурсы у одного из процессов с целью продолжения вьшо-"—•« другого. Как обнаружить? Если выполнение критической сад» превышает заданный интервал времени, выполвенне про принудительно завершается, общий ресурс восстннавлишч! таким, каким он был до входа в критическую секцию. Это : \ м аффективный метод, чем предыдущий, но надо аапоминатьяЦ яние при входе в любую критическую секцию. Очередной подход предполагает, что тупик возникает к» редко, поэтому ни средства предотвращения, ни средства обц-, жения не используются. Если приложение выполняется мнив» долго, то оно просто снимается (пользователем или система!)!» пускается заново. 3.8. Модели и механизмы синхронизации 3.8.1. Монитор как механизм синхронизации Определение монитора
Монитор используется для предотвращения взаакво ? • ключения, когда одив ресурс одновременна может использмЯ ся только одним процессом. Монитор [6/ — это объект (кл специального типа- Все переменные этого объекта внутрешп т. е. имеют атрибут защиты private. Среди переменных ecu М или несколько объектов специального типа по одному д,м «М дого защищаемого ресурса. Эти объекты называются услоымЬ Среди функций есть внутренние (имеют атрибут private), кетц* может вызывать только сам монитор, и внешние (имеют aTjrt" public), которые могут вызывать другие приложения. Для вий применяются только впутренние функции. Каждому усляв соответствует своя очередь, куда ставятся процессы, если илг» лируемый условием ресурс занят. Установка и снятие блокировки выполняются с помош функций монитора. Функции монитора выполняются в рек-» взаимного исключения, что гарантируется самим моей-* Это означает, что при входе в любую функцию монитора ннша другие функции монитора не могут быть запущены до < < шекия начатой функции. Такие функции обычно впзыы*^
ритивами1. В работе [13] приводится модель монитора. Мо•ц рассматривается как комната с одной дверью для входа и для выхода. После входа в комнату одного человека (заИй ресурса одним процессом) входная дверь закрывается до тех Ж а ка чечовек не выйдет в выходную дверь, т.е. другой проЬ те может захватить ресурс до тех пор, пока его не освободит •адщий процесс. Функции м о н и т о р а
Монитор имеет функцию и н и ц и а л и з а ц и и , б л о к и р о в а н и я , Цфшеннн состояния (есть ли процессы, которые ждут доступа I , ,vy) и функцию сигнализации процесса. фикция инициализации Init формирует н а ч а л ь н ы е знащгл внутренних переменных и выполняется один раз при его г ши. ФУНКЦИЯ блокирования процесса Wait посылает сообщение ИГг зо ОС о необходимости блокировании процесса, если ресурс, требуется для продолжения его работы, занят другим щкгтам. При этом кванты процессорного времени заблокировпгау процессу не выделяются на все время, пока процесс за>.-мрован. Функция определения состояния Status возвращает значение ГА'-ли ни один процесс не ждет ресурс, которым управляет •л,- гр, и false в противном случае. Ф у н к ц и я вызывается д л я ^к» тения наличия ждущих процессоров в очереди. Функция Signaled извещает ОС об освобождении заданного 1>" В случае получения сообщения об освобождении ресурса ОТ разблокирует процесс из очереди, если он есть, и запускает ft, аачнная с того места, в котором он был остановлен функцией т.
С помощью перечисленных выше функций обычно опредеался функции, которые можно вызывать в пользовательской цтграмме для обеспечения синхронизации. Так как все перечисленные выше функции являются принтами, проблемы взаимной блокировки при выполнении этих t шзш не возникает. Ниже более подробно рассматриваются типичные проблемы, (•пикающие при управлении разделяемыми (совместно испольцишми) ресурсами, и их решение с помощью мониторов. "ушивом называется последовательность команд, которая должна выпол««1Ш!даное целое и не может быть прервана другим процессом.
115
Примеры использования мониторов
Пример 1. Рассмотрим схему использования монитора ив чая, когда каждый процесс имеет свою критическую секцию. ция инициализации устанавливает логическую переменную йл * = false, что означает, что любой процесс может войти в кр» скую секцию. Обозначим условие CritlcalSection. Определяя и не функции: CSBegin начало критической секции и CSS* конец критической секции. СSBegin()(if(!Buzy) Busy = true; else CnticatSecbon.Waitf).} CSEnd(l{Busy ~ false; CriticalSection Signaled^;}
Определим структуру процессов с критическими сейши Пропесс I CSBegin();
Процесс 2
Критическая секция процесса 1
С SBeginf), Критическая секция прощ а
CSEnd()
CSEndf)
В этом примере порядок выполнения критически* оЦВ в процесспх может быть произвольным. Пример 2. Пусть процесс 1 пишет запись, а процесс • эту запись. Очевидно, что процесс 2 может прочесть эяпнсы после завершения ее создания. Писать можно, если ещеве нанялись операции чтения или предыдущая операция чтея ««• завершена. Читать можно, если завершилась операциязящ *» Определим переменную bRead, которая равна истнвв. выполняется чтение, и переменную bWrite, равную истин* Mflf мя записи данных Зададим функции BeginWrite и EndWrite, которые вызывать до и после операции записи в буфер: BeginWrite ()(it (lbRead)(bWrite = true; Read-Wait (I.) EndWrite (){h Write = falsa; Read.Signgled ();)
Заметим, что переменные bRead, bWrite являются и н щ ними переменными монитора. Поэтому их значения ыо".»<Щ изменены только функциями монитора. З а д а д и м ф у н к ц и и BeginRead и EndRead, которые HCOMV
мо вызывать до и после операции чтения из буфера: BeginRead (X tf ('bWrite)f bRead = true: Write.Wait ();) EndRead (tfbRead = false; Write Signaled ():} 116
Функция инициализации задает значения переменных е-true; bRead = false. З н а ч е н и е bWrite = true о б е с п е ч и в а е т
m нежность чтения данных до их записи. Использование функций процессами Процесс 2 (Read)
Процесс 1 (Write) bpn Write ();
BeginRead ();
Жирование записи;
Чтение записи;
r
EndRead ();
~lWnte ():
'аметпм, что в данном примере должен быть только один рцк для записи. Пример 3. Пусть один и тот же файл создается и редактиру•*«зроцессами-писателями и читается процессами-читателями. : .устожим, что приоритет имеют ч и т а ю щ и е процессы, т.е. ю есть хотя бы один читающий процесс, запись начаться не яжг.
В этом примере количество процессов-читателей и процеср-пгагелей может быть произвольным. Определим внутренние переменные м о н и т о р а nReads и t"es, которые обозначают количество процессов-читателей прпцессов-пиеателей, соответственно. Так к а к одновременно ... ь могут несколько процессов, но при этом ни один из проI» овне должен писать, то условие, позволяющее читать, имеет '(лWrites =-0 && nReads). Так как писать может одновремен• | 1ько один процесс, при этом другие процессы не д о л ж н ы ни I ь, ни писать, условие разрешения на запись: if (п Writes ==1 & I 'iReads). Анализ условий чтения записи показывает, что знание переменной, управляющей процессами-писателями, равно и или 1, т.е. может задаваться булевской переменной. Таким об[* «м, внутренними переменными монитора я в л я ю т с я nReads ЬШе = true, если есть процесс, который пишет. Д л я решения ийзадачи понадобится монитор с двумя условиями. Обозначим , ^ответственно, Read и Write. Монитор для управления этими ;• тессами должен содержать внешние функции: Начало чтения
BeginRead
Конец чтения
EndRead
Начало записи
Begin Write
Конец записи
EndWrite
117
void BeginRead (){ nReads++; if (!bWrite){// Никто не начал писать Write. Wait();// He даем начать писать Read.Signaledf);// Активизируем функцию чтет •
}
}
void EndRead (){ nReads—; if (nReads == 0){// Больше нет читающих, можно начать //писать Write. Signaled ();
}
}
void BeginWrite (){ //Нет пишущих, нет читающих if (nReads ==0 && IbWrite) { bWrite = true, Read. Wait (); Write. Signaled ();
}
}
void EndWrite (){ bWrite = false; If (nReads) Read. Signaled ();
}
else Write. Signaled();
} Инициализация: I nit () (bWrite = false;
NReads = 0;}
Пример 4. Встреча n процессов в заданной точке. Пуст процессов выполняют сбор информации о некоторых объект а процесс п + 1 выполняет обработку собранных данных, пр обработка может быть начата только при условии завершения ^ ра информации всеми процессами. В качестве внутренних переменных монитора испольггч> целочисленная переменная Count. В качестве условия teMee) пользуется условие, значение «истина» для которого устанавь вается, если Count = п, где п — число процессов, которое дог встретиться в заданной точке. 118
Функция Init: tffflcaint = 0;}. Внешняя функция Meet имеет вид: Ш() (Count++; if (Count < п) lsMeet.Wait(); else lsMeet.Signaled();} Недостатки мониторов 1. Активизация ожидающих процессов в ы п о л н я е т с я с помоai сигнала (функция Signaledf)). По этому с и г н а л у необходимо t "йблвцы выбрать процесс, который ждет заданный ресурс, и раз1-<;»ровать его. При этом за время в ы п о л н е н и я этой о п е р а ц и и ргорую выполняет не монитор, а другой процесс ОС) состояние гарантированно не изменилось. 2. Если данный сигнал ни один процесс не ждет, он пропадает. 3. Неопределенно поведение монитора, если несколько прот»1 IB ждут этот сигнал. 3.8.2. Семафорные примитивы Понятие семафора
Дейкстра ввел два примитива, используемые д л я с в я з и про» об. Эти примитивы оперируют н е о т р и ц а т е л ь н ы м и ц е л ы м и щами, которые называются семафорами (S). Д л я семафоров «I -делены операции inc (V(S)) и dec (P(S)), к о т о р ы е д о л ж н ы быть длимыми, т.е. во время выполнения этих о п е р а ц и й не д о л ж н о ; ггьперехода на другой процесс. Операция P(S) соответствует выг.-евию ресурса, операция V(S) — освобождению. Если несколько процессов требуют одновременного выполнена разных операций над одним и тем же семафором, то эти оперцки выполняются последовательно в п р о и з в о л ь н о м п о р я д к е ; (. ли более одного процессаждут Р операции и семафор становится ггжптельным, произвольный процесс м о ж е т п о л у ч и т ь доступ с?виафору. Использование семафора для к р и т и ч е с к о й секции
Semaphore s = 1; Процесс 1 Р($); /"Критическая секция */
Процесс 2 P(S); /*Критическая секция */
т.
V(S); 119
В данном случае семафор называется двоичным семафс к. Он используется к а к замок, который запрещает прерывание кр тической секции для выполнения такой же секции в другом пр>цессе. Этот метод легко распространяются на следующие слу~ — количество конкурирующих процессов более двух; — количество ресурсов более одного. Второй случай будет рассмотрен ниже. Пример 1. Пусть 3 процесса д о л ж н ы выполнять до к единственному принтеру. Если начата операция печати ода процессом, он не может быть прерван другими процессами Щ выполнения печати. Выделим семафор S = 1 для управления процессами. Пшя под S выделим в области памяти, доступной всем процессам. Структура каждого процесса имеет вид; P(S); Вывод данных на принтер V(S); Рассмотрим состояние семафора S, предполагая, чтоперв«х начал выполняться процесс Р1, затем Р2 и в конце — РЗ. Пи Я при выделении первого кванта времени каждому процес у достигает критического участка. Пусть критический участок полняется за два кванта времени. Таблица состояний S Номер кванта времени
Имя исполняемого процесса
Значение S
1
Р1
0
Пустая
2
Р2
-1
Р2
2
РЗ
2
Р2,РЗ
2
Р1
1
РЗ
3
Р2
1
РЗ
4
Р2
0
Пустая
5
РЗ
0
Пустая
6
РЗ
1
Пустая
120
Очередь заблокирована процессов
l
JK видно из данной таблицы, S = 1 означает, что ни один из г .'сов не выполняет критической области. и=Оозначает, что один процесс выполняет критическую обri виодин из процессов не заблокирован. S < 0 означает, что один процесс выполняет критическую «ago. Количество заблокированных процессов, стоящих в оче-
Прияер 2. Блокирование и разблокирование процессов. In процесс 2 должен разблокировать процесс 1. Semaphore s = 0; "рот 1
Процесс
2
P(S);
ftk/Заше сигнала от процесса 2*/
ГПоспать сигнал процессу 1 */ V(S);
Пример 3. Пусть один процесс записывает данные в буфер Иг: ечати, а другой процесс выбирает эти данные и печатает. J .-.K случае первым должен отработать процесс 1, процесс 2 р*<гначинать работу только после заполнения буфера. Так как в буфер и извлечение из буфера не могут быть вьшолнены ш конолитные операции, будем их выполнять в критической ••«гая, что позволит исключить их одновременное выполнение. ; «организации критической секции будем использовать сема№ Кроме этого, определим число свободных f и занятых буфера1 Сначала рассмотрим решение этой задачи для одного буфера. АГВСЬ
Semaphore s = 1; f=1;b
=
0;
Процесс 1
Процесс
While (1){
While
ГФормироеание записи */
Р(Ь); P(s);
Р
№
2
(1){
/*Выборка данных из буфера V
Т
ГЗапись данных в буфер*/
V(s)
Щ:
V(f) /*Их печать }
W
121
7
В случае, если число буферов равно п, необходимо в пер> менную f записать число п, а в переменную b — число 0. Сема»! по-прежнему принимает два значения — 0 и 1. Семафоры т а к ж е можно использовать для распределение! однородных ресурсов. Использовоние семафоров для распределения множество ресурсов ( О б щ и е семафоры)
До сих пор рассматривались двоичные семафоры, для ка-> рых возможными значениями я в л я ю т с я значения 0 и 1. Обвич н а з ы в а ю т с я с е м а ф о р ы , д л я к о т о р ы х допустимыми являстч значения п, п — 1, ..., 0. Поведение такого семафора может V смоделировано с помощью двоичных семафоров. Каждый об:;:й семафор может быть представлен целой переменной N и оттч двоичными семафорами а и Ь. Здесь а — двоичный семафор, в» торый используется к а к семафор для организации критиче i секции. Семафор b используется д л я организации ожиданияоа» бождения ресурса в случае, если свободные ресурсы отсутствие Р е а л и з а ц и я операций Р и S для общего семафора приве к ниже. Реализация операции Р
Реализация операции V
Р(в);
Р(а);
N-;
N++;
if (N
<=-1){ V(a);
lf(N<=0) Рф);
V(b);
}
V(a);
else Щв);
Вначале а = 1 (критическую секцию можно начинать); b •-1 (все ресурсы не израсходованы); N — число ресурсов, которые управляет семафор. Реализация операции Р. Войдя в критическую секцию (Р(Я количество ресурсов уменьшается на 1, и, если ресурсы еще< (N > — 1, т а к к а к у м е н ь ш е н и е ч и с л а ресурсов выполняется» и с п о л ь з о в а н и я этого ресурса), то разблокируем критиче:ы секцию (V(a)). Если ресурсов больше нет (N < - 1 ) , то разбъ кируем критическую секцию (V(a), иначе не сможем войти г 122
ждения ресурсов), входим в критическую с е к ц и ю ожида•кдения ресурса (Р(Ь)), пока п о я в я т с я свободные ресурКфорЪ). Рилизация операции V. Войдя в критическую с е к ц и ю (Р(а)), творесурсов увеличивается на 1, и, если ресурсов все е щ е • О ,0), ждем их освобождения (V(b)). Если ресурсы есть, то «изкритической секции (V(a)). \'ричный семафор используется, если необходимо управ. выделением N ресурсов для М процессов (N < М). В этом означение переменной, соответствующей семафору, д о л ж н о т \ JJIBEC А. Для выделения и освобождения ресурсов использу«примитивы Р и У, как для двоичного семафора. Пример 1. Пусть для вывода данных используется N буферов. В этом случае в общей области памяти д л я процессов, котоpv * луг писать в эти буферы, в S запишем значение N. Запись »И»р и его использование в каждом процессе имеет вид: PIS); Запись в буфер; Использование буфера; Ш Пример 2.
П'тть «Писатели» пишут в N буферов. Пусть «Читатели» Ивгтсодержимое буферов. В этом случае «Писатели» могут питолько в том случае, если есть хотя бы один свободный буфер. •VimiH» могут читать, если есть хотя бы один з а п о л н е н н ы й •н
D этом случае понадобится 2 семафора — один д л я з а д а н и я *з свободных буферов, другой — д л я з а д а н и я з а н я т ы х . Обо•'шк эти буферы, соответственно, Free и Busy. 'Начальная установка */ Fw-KBusy = 0 "Процесс писатель V Ше IЕсть что писать) PfFree); Есть куда писать? Запись в свободный буфер; V(Busy); 'Процесс читатель*/
123
While (Надо писать) { P(Busy); Есть что читать? Чтение из занятого буфера; Освобождение буфера; V(Busy);
} 3 . 8 . 3 . С р а в н е н и е м о н и т о р о в и семафоров
Примитивы Монитора более просты по сравнению с i митивами Семафора. Примитивы Семафора могут быть зованы с помощью примитивов Монитора и других oneps..f-i (сделайте это!). Сравнение р е а л и з а ц и й критических уча па с одним и несколькими однородными ресурсами показывает Щ использование семафоров упрощает программирование, по г щ в современных ОС вместо мониторов обычно используются с-*< форы. В современных 64-битных процессорах есть команды. реализации семафоров.
3 . 9 . К о м м у н и к а ц и я м е ж д у процессами Часто процессоры бывают зависимыми не только по лам, как рассмотрено выше, но должны передавать друг д] " значительно больший объем информации. Проблема связи процессами является актуальной, так к а к каждый nponei t пользует свое адресное пространство и передача данных чер°*и раметры или другие общие области для процессов не примени» Д л я обеспечения связи между процессами используются рam способы: сообщения, модель «клиент — сервер» и др. 3.9.1. Использование с о о б щ е н и й для о р г а н и з а ц и и связи м е ж д у процессами. Модель производитель-потребитель
Один процесс (производитель) посылает сообщения дру* процессу (потребителю), используя для этого общий буфер, прг ставляемый операционной системой. Сообщение имеет фик 11 ванный размер, и размер буфера тоже фиксированный, по::* общее количество сообщений в буфере ограничено. 124
Правила использования. 1. Одно сообщение можно послать только один раз. 2. Попытка послать сообщение в полный буфер блокирует ip.<ecc, который делает эту попытку. 3. Попытка принять сообщение из пустого буфера блокирует цгхгес, который делает эту попытку. Процесс-производитель формирует сообщение и помещает язбуфер. Процесс-потребитель извлекает сообщения из буфера. Очередность обработки сообщений может быть любой (оче|(а.,стек), но для обработки используется монитор, который обеИглввет монопольный доступ к буферу. Схема может быть обобщена на случай многих производителе потребителей. В этом случае обеспечивается, что сообщение быть получено только одним потребителем, но конкретный итель не может быть обеспечен. Функции монитора для управления: BufPush (запись в буфер ;спия), BufPop (извлечение сообщения из буфера). Условия: NotBlankBuf — буфер не пуст, NotFullBuf — буфер рашый. Переменные: п — текущее число сообщений в буфере, N — альное количество сообщений. BufPush (Message)f Щп — N) NotFullBuf. Wait(); л++;
Buf.Push (Mesage); NotBlankBuf.Signal (); Message BufPop (){ Iffn-'O) NotBlankBuf.Wait (); Message = Pop();
mlMMSignalfl; J Функция инициализации: /г = 0; 3.9.2. Использование сообщений для о р г а н и з а ц и и связи между процессами
Если необходимо организовать с в я з ь м е ж д у п р о ц е с с а м и Ь передачи информации, как в прошлом случае, можно т а к ж е 125
использовать сообщения, так как они обеспечивают оп ный порядок доступа, сообщение можно получить толь того» кпк оно послано. В этом с луч не используются баловые^^ дии Send — послать. Receive — получить. Сами сообщения записываются в очередь сообщений, мер, еслп не учитывать возможность переполвення и во лучения из пустой очереди: struct
QUBUE{ MESSAGE TabtelN]; intHead. Teit;
}: S e n d (MESSAGE Message. To){ Tabte[Tail++] = Message; If (Tail -= N) Tail = 0;
) MESSAGE Receive(From)( MESSAGE Message; Message = Table[Head++J, If {Head == N) Head = 0.
) Функция инициализации: Head = Tail =0; Выше приведена только схема функции, в каэд .< ш кретвом случае возможны разные типы сообщений, ншрпф сообщения, могут быть постоянной и переменной длины. Д*» зания приемника для сообщения может задаваться пня щш • (прямая адресация) или промежуточный адрес (почтовые куда складываются сообщения) — косвенная адресащи Е « почтовому ящику соответствует только один прнемнпк, почтовый ящик называется портом. В случае исиочьэом чтового ящика необходимы дополнительные функции ли и разъединения {online, offline). При статической связи неч» цессом-получателем и портом имя порта однозначно о процесс-получатель, как в случае прямой адресации. Для организации связи между процессом и почтоиш ком используются следующие схемы. 1. Схема «Производитель — Потребитель», когда ящик — это буфер с сообщениями. 2. Схема типа общей точки, когда Процесс, передаю общение, блокируется на время, пока сообщение пр из почтового ящика. Заметим, что этн схема является 12G
и предыдущей, когда буфер может содержать максимум «общение. метим, что для работы с сообщениями ОС UNIX используры (трубы) и схему «Производитель — Потребитель». J.9.3. Использование клиент-серверной м о д е л и для связи процессов
Процесс-сервер должен оказывать услуги процессам-клиенIU. Процесс-сервер обычно связан с портом, куда посылаются к-ссы клиентов. При отсутствии запросов процесс-сервер забло• ш или выполняет пустой процесс. В качестве запроса может fctb необходимость пересылки результата процессу-клиенту, 1 г 14 случае последний должен сообщить порт, на котором он OR результат. Процессов-серверов для выполнения запросов м>т быть несколько, в этом случае к а ж д ы й из серверов может Н ,:шть запрос. В этом случае все эти процессы должны быть Ьмыс помощью почтового ящика. Итак, рассмотрены основные схемы, по которым процессам ^предоставляются услуги: вызов процедур монитора или ци1!И"кое обслуживание процесса путем пересылки сообщения.
3.10. Особенности мультипроцессорных систем (спин-блокировка, реентерабельность) Пусть при выполнении процесса дошли до критического гт>—ка. который в настоящий момент выполнять невозможно. | -тчве однопроцессорной системы данный процесс блокируШ, выполняется переход на другой процесс, т.е. выполняется щшлючение контекстов. Но данное переключение требует дотчво много процессорного времени. С другой стороны, возv чао, что критический участок можно будет продолжить спустя г"~орое время. Если предположить, что работу данного проора блокирует другой процессор, вместо переключения более Активным является ожидание до тех пор, пока можно будет рцмжпть первый процесс. В этом случае используется так наадаемая спин-блокировка (Spinlock), т.е. ц и к л с заданным чисюм повторений, который управляет временем ожидания. Если н это время критический участок будет свободным, то первый Агцесс продолжит свое выполнение Spinlock и использует ОС для гашения своими процессами. 127
Пример. Пусть используется двухпроцессорная систэв Пусть первый процессор выполняет поток, который извт элемент из очереди отложенных функций (DPC), а второй г* добавляет элемент в эту же очередь. В этом случае структураг> граммы для обоих процессоров: do{ Пытаемся получить DPC Spinlock }while (DPC Spinlock занят); ; Делаем Spinlock занятым Выполнение требуемой операции; Освобождаем DPC Spinlock; Участок кода, который выполняется при занятом Spinlock до
Заметим, что использование такого механизма для однсг. цессорных систем смысла не имеет, так как, если процессора» данным процессом, он не может одновременно выполнить р«1и для другого процесса. Для реализации Spinlock используется команда процессор которая позволяет проверить содержимое заданной области i если это состояние равно заданному, то его переустановить. Да процессора типа 1-32 используется команда setcc, которая у-» навливает значение 1, если заданное в команде условие выпш ется, и устанавливает значение 0, если условие не выполнят Пример1. ; Делаем Spinlock занятым Стр [DPC_Spin Lock], 1 Setne [DPC_Spin Lock]; Если занятый — делаем его свобо
3 . 1 1 . Вопросы и з а д а ч и 1. Как называется объект, которому выделяется виртуальное® ресное пространство, время процессора? 2. Возможен ли рекурсивный вызов задачи? 3. За счет чего обеспечивается невозможность рекурсивного кх> ва задач? 4. Какие команды используются для переключения между ы чами? 1 Предполагается, что для свободного Spinlock установлено значение 1, л » нятого — 0.
128
Есть ли ограничения на уровни приоритетов для двух задач, между которыми происходит переключение? о. Почему в списке указателей на стеки в TSS нет указателя на стек 3 уровня привилегий? В каком случае необходимо использовать средства синхронизации? • Что такое критическая сек ция? ч Используя монитор или семафор, напишите код для чтенияиписи данных, если одновременно писать могут т процессов, а читать любое число потоков. III. Напишите ассемблерный код, реализующий примитивы для "емафора.
129
4 . П Л А Н И Р О В А Н И Е И ДИСПЕТЧЕРИЗАЦИЯ
Цели изучения р а з д е л а : 1. Сравнить различные алгоритмы, к о т о р ы е используются •» тесняющего и невытесняющего планирования задач в ОС •• как использование приоритетов, сравнение производители «справедливые схемы». 2. Описать отношения между алгоритмами диспетчеризоции ч ро личными предметными областями. 3. О б с у д и т ь типы п л а н и р о в а н и я : к р а т к о с р о ч н о е , среднеср(-долгосрочное, ввод-вывод. 4 Описать различия между п р о ц е с с а м и и потоками 5. Сравнить статические и динамические подходы к планиром-я 6. Обсудить необходимость приоритетного обслуживания и шх вания по с р о к у завершения. 7. Указать примеры использования алгоритмов планирования втаобластях к а к дисковый ввод-вывод, планирование проектов <
4 . 1 . О п е р а ц и и планирования и диспетчеризации Наиболее критическим ресурсом является центральный цессор. Наличие нескольких процессоров в многопроцессо •» системе усложняет алгоритмы управления временем прош ров. Д л я управления временем процессора используются мо, планирования и диспетчеризации. Планирование — этооргш зация очереди процессов, готовых к выполнению. Диспетче ция — это выбор процессора для конкретного процесса, готок исполнению. Обычно процедуры обслуживания очереди пр цессов и выбора процессора выполняются одним модулем, в э i случае модуль носит общее название — иланировщик-диспегч Исключения составляют системы реального времени. 130
| череди готовых процессов могут стоять процессы разных
i
сложенные процессы — процессы, которые были прерваы -язи о необходимостью ввода-вывода или доступа к другим гт'чным ресурсам; aoBbte процессы — которые только запущены и еще не ПОШЕТОВ времени;
процессы, для которых истек квант времени. Планировщик по-разному управляет процессами р а з н ы х >ритм планирования определяет, к а к о м у из процессов Iвыделен квант времени, и размер этого кванта. Н и ж е бумотрены различные алгоритмы планирования. Пример атма планирования: сначала выбираются отложенные про1 "ш они есть (это обеспечивает наиболее быс трую реакцию pi '.еиня на завершение операции ввода-вывода, например, М 1 ктавиатуры); если отложенных процессов нет, то выбира«тальвые процессы из очереди готовых процессов. я программной реализации такого планирования можно к- лать двухстороннюю очередь. О т л о ж е н н ы е процессы «клются в голову очереди, остальные готовые процессы — ptMCT. Выборка всегда выполняется с головы очереди. В этом ! ие первым выполняется процесс, который был отложен поН-чиожно использование очереди с приоритетами. Каждому Щьп в очереди готовых процессов ставится в соответствие ^.тптрт (целое число). Приоритет определяется статическими I at мическими характеристиками процесса. К статическим ^итррвстикам относятся требуемый размер п а м я т и и ожиJM процессорное время, ожидаемый объем ввода-вывода. Им^итет может быть назначен пользователем, этот приоритет № щределяет статическую характеристику. Д и н а м и ч е с к и е .if , теристики изменяются в процессе выполнения программы. It тшические характеристики влияет поведение процесса при 1ЦШСПЦИХ выделениях кванта времени (объем памяти, объем •а-вывода), а также приоритет может быть временно увели131 *в* фи •гнтета I пение лх .шеквантов для приоритета истало приложения действует времени. приложением обычно только выполнен выполняется на переднего протяжении запрос плана. в сторону ввода-вывода, одного Динамическое увеличения или или не-
Системные процессы, как правило, имеют такой тет, как и пользовательские процессы. Исключение «.« н системные процессы для управления внешними устро Л При планировании приходится учитывать многочисленные*" ватели производительности, малое время простоя, разумному мя ожидания заданий пользователей, чтобы ви одно я» и| не простаивало вечно. Для обеспечения функционирования планировщика» I пустой очереди ОС имеет так называемый «холостой* пром торый запускается в этом случае. Этот процесс выполняете!! пор, пока не появится хотя бы один готовый процесс в о < В современных многопроцессных системах не все про равноправны. Системные процессы, как правило, имеют высокий уровень приоритета. Пользователь тоже может ч| разные приоритеты своим приложениям. Использование ~< очереди с приоритетами в данном случае очень сложно. В »• менных ОС обычно для каждого уровня приоритета вен i свою очередь. Так в ОС WINDOWS используются 32 урош ^ вилегии 0 .. 31 и, соответственно, 32 очереди. Чем болы тем выше уровень привилегии процесса. 32-битное чис, | очередей) соответствует всем очередям, i-й бит уставов» i если очередь, соответствующая этому уровню привилегяв.вф ста. В этом случае алгоритм диспетчеризации имеет вид. for(i
}
= 31;i>=0;i-)( if(flag[>l)< Выборка из гоповы очереди для уровня привилегии | Выделение процессу кванта в р е м е н и процессора. }
Выборка
холостого
процессе;
В некоторых ОС приоритет изменяется в диапазоне С J так как такой уровень привилегии помещается в один * дается в очереди вместе с другой информацией о пронеси. ]
4.2. Алгоритмы п л а н и р о в а н и я 4.2.1. Ц и к л и ч е с к о е п л а н и р о в а н и е
Относится к бесприоритетному планированию. После ш шевня кванта времени процесс станится в конец очереп \ цессы для исполнения выбираются с головы очереди. Ди •
•Нбольшое значение имеет размер к в а н т а времени. Если «[времени очень большой, то последним процессам в очереди вига долго простаивать до начала их выполнения. Уменьшу размера кванта времени улучшает обслуживание более щг, !их процессов. Выбор слишком маленького значения кванц-неии приводит к тому, что размер кванта соизмерим со вре• и, требуемым для переключения процессов, это увеличивает : "и времени (накладные расходы). Поэтому размер кванта | м в необходимо выбирать таким, чтобы накладные расходы I Т' ЮСходили заданной величины. Т а к а я схема планирования к^шуется обычно в системах с большим числом пользовате>! В этом случае выбирается время ответа (время, в течение *w>iroкаждый процесс в очереди получит квант времени). Д л я Iвеяния размера кванта времени время ответа делится на Itv процессов в очереди. Этот размер кванта используется для RI процессов в очереди. После выделения кванта времени всем 9 :*: ;ам размер кванта пересчитывается с учетом новой длины Ярл. Если размер кванта получается слишком маленьким, он «вшивается равным заданной величине. При этом время оти» «личится. Но потери, связанные с переключением, уменьЖ», а значит, увеличится общая производительность системы. 4.2.2. Очереди с обратной связью
(^пользуется п очередей. Готовый процесс в первый раз по•irfca в очередь № 1. После истечения первого кванта он поме-
ргл в очередь № 2 и т.д. Планировщик выделяет процессорное -напроцессу, который находится в очереди с м и н и м а л ь н ы м но«ти. В этом случае наивысший приоритет имеют новые процесЫополвнтельные потери ресурсов требуются для организации г/'ты нескольких очередей. Для уменьшения этих потерь слуг»: ая очередь может выбираться после истечения т квантов. 4.2.3. Приоритетное п л а н и р о в а н и е
Время процессора предоставляется наиболее приоритетному ty. Этот процесс выполняется до тех пор, пока не будет (Ж)етн или заблокирован в связи с необходимостью вводаш t&. Если вытеснение не разрешено, то он продолжается до иг,тения кванта времени даже в том случае, если в очереди ииатся процесс с более высоким приоритетом. Если вытеснение 133
разрешено, то управление будет передано процессу с боли • ким приоритетом до завершения кванта времени. Вытесдг i процесс попадает в очередь готовых процессов. Заметим, что вытеснение требует определенных затри.! I до завершения процесса осталось мило времени, вытеснен] целесообразно. Вытесняющее планирование особенно ней приятно для процессов, которые выполняются длительное и имеют невысокий приоритет. Если используется общая очередь для всех приоритет | то она должна быть упорядоченв в порядке убызання врнорвгт В этом случае всегда выбирается первый элемент иэ очеред* » пнсь в очередь процесса с учетом приоритета требует в cwa* просмотра половины очереди. Это уже скорее ве очередь, рядоченный список. Использование разных очередей дла уровней приоритетов упрощает упрааление очередями. Возможна зависимость размера кванта от приоритет»:^] выше приоритет, тем больше размер кванта времени. Э* А спечивает более быстрое выполнение высокоприоритетны» щ цессов. В современных ОС наряду со статическими приората которые определяются при создании процесса, всполилЩ динамически приоритеты. Динамический приоритет иэмеиЩ в ходе ожидания и выполнения процесса. Возможна исполни нне линейно возрастающего приоритета [9]. Каждому присваивается базовый уровень приоритета. Приоритет увев вается на заданную величину а во время ожидания и на Ь во время выполнения. Если выбрать 0 < a S Ь, то пропесаш | полняются в процессе их поступления, если 0 > Ь ь а, то п| сы обслуживаются в порядке, обратном поступлению в ottpa 1 Если О S Ь < а, то приоритет процесса, находящегося в н ожидания, растет до тех пор, пока не станет равным nj исполняемого процессе. Начиная с этого момента. процм< делить кванты времени с исполняемым процессом. Так KAEI I такой момент наступит. Заметим, что динамическое изменение приоритет, полняется по-разному в разных ОС. Так, например, в WI4I используются следующие правила установки дивамичешп i оритетов. При первом запуске процесса его уровень вриыи увэличизается на несколько единиц по сравнению со статичен уровнем. При последующих запусках уровень привилегий жается до статического уровня. Это позволяет быстро в-г.я| 134
fBf ы, которые требуют не более одного кванта времени. АнаЬькн механизм используется для о т л о ж е н н ы х процессов. тшучения сигнала о завершении ожидаемой операции урот привилегии процесса увеличивается на несколько единиц по фквию со статическим уровнем. Могут быть другие правила И'Лческого определения уровня привилегии. 4.2.4. Адаптивно-рефлекторное п л а н и р о в а н и е
Планирование выполняется с учетом потребности в памяI гддесса. Оценка требуемого объема памяти определяется по •игм памяти, обнаруженным при предыдущем выделении ^ ±га времени. Предполагается, что при очередном выделении шла памяти потребуется столько же. Процессу выделяется оче•ягщквант времени при наличии требуемой свободной памяти, hue р выделяемого кванта времени обратно пропорционален Ммому объему памяти. „кое планирование «заставляет» пользователя оптимизиМ ьсвои программы. 4.2.5. Вытесняющее и невытесняющее п л а н и р о в а н и е
Как следует из анализа приоритетного планирования, возm id 2 режима использования этого планирования: без вытесr-iя н с вытеснением исполняемого процесса. Использование мнения усложняет алгоритм планирования и требует допол«тьных вычислительных затрат. Заметим, что вытесняющее жирование для обработчиков прерываний может быть реализо№ та аппаратном уровне с помощью контроллера прерываний. sni-ияющее и невытесняющее планирование для программных ( т должно быть реализовано ОС. Выбор зависит от конкретнее. 4.3. Политика планирования 4.3.1, Определение политики п л а н и р о в а н и я
Алгоритм планирования д о л ж е н р а з р е ш и т ь н е с к о л ь к о шктных ситуаций: быстроту реакции, хороший отклик на • -)вые работы, исключение голодания процесса (процессу не •ИЕмется квантов времени достаточно долго), согласование г-л низко-и высокоприоритетных процессов и др. Множество гклит, которые определяют, когда и к а к и м процессам выделить 135
квант времени, называется политикой планирования Ки « говорилось выше, большинство современных ОС использ нологию разделения времени, а именно: Несколько процессов выполняются в режиме много»!» передачи процессорного времени от одного процесса ж т.е. время процессора делится на кванты. Если текущий п] не успел завершиться за выделенный ему квант времен! , ч изойдет переключение процессов. Разделение времени р ется с помощью обработчика прерываний для таймера, я дополнительного ПО для переключения процессов и Приостановленным процессам, которые ждут каких-то с. кванты времени не выделяются. Политика планирования базируется также на рав« вии процессов в соответствии с их уровнями привилегий ГШ I ные алгоритмы иногда используются для определения и приоритета процессу, но, в конце концов, именно этот ц определяет, когда процессу выделяется время. Для Бо.иан современных ОС приоритет — величина, которая дмшхвт изменяется с учетом того, что делает процесс, и перисдетп! меняет приоритет процесса: за счет этого для процессов, кст было отказано в обслуживании достаточно много времен, ч вень приоритета постепенно станет высоким, и время ем. N выдеяено. Одновременно процесс, который выполняете* М штрафуется за счет уменьшения уровня его приоритета С точки зрения требований к процессорному времев щ цессы делятся на 2 класса: процессы, требующие много в^»*» для ввода-вывода данных, и процессы, которые требужгт « процессорного времени. Обычно первому клессу процесс I присваивает более высокий приоритет, чем второму. За* «г** 1 приоритет, который назначается ОС, может изменяться н^М се исполвения приложения, поэтому такой приоритет на чл динамическим. 4 . 3 . 2 . К л а с с и ф и к а ц и я п р о ц е с с о в с т о ч к и зрение планирования
С точки зрения планирования процессы делятся натр»" Интерактивные процессы — взаимодействуют H-I ственно с пользователем через клавиатуру и (или) мьшкц". ввод данных выполнен, процесс должен быстро отклику Средняя задержка должна быть между 50 и 150 ми чти
ечения быстрой реакции на ввод-вывод данных т а к и м присваивается высокий д и н а м и ч е с к и й п р и о р и т е т , классу процессов относятся текстовые редакторы, графишюжения и др. Макетные процессы — они не требуют в з а и м о д е й с т в и я оввтелем, часто выполняются к а к фоновые процессы, процессы не требуют высокой реактивности, поэтому плаЕ ; К назначает таким процессам невысокий динамический ет. К этому классу относятся компиляторы, инструменте средства для поиска в базах данных, процессы для научхлений. цессы реального времени — э т и п р о ц е с с ы п р е д ъ я в л я ю т
рогие требования к программе планирования. Такие проникогда не должны блокироваться низкоприоритетными миидолжны иметь минимальное время реакции на вводдаввых. Динамический приоритет, который назначается процессам, наивысший. К этому классу обычно относятся мы для взаимодействия с физическими устройствами, тш для управления роботами и др. Цляуправления приоритетами можно использовать системювы. Системные вызовы (функции API) для управления тами на примере ОС W I N D O W S будут р а с с м о т р е н ы
4.3.3. Вытеснение процессов
вытеснение процесса выполняется в том случае, если происходит в состояние «Готов к исполнению», но при этом ор занят выполнением процесса, динамический приори« торого ниже. Кроме этого, процесс может быть вытеснен, •вершился квант времени, выделенный д л я процесса. ПриЯусгь выполняются два приложения: текстовый редактор и пор. Текстовый редактор является интерактивной проL , поэтому динамический приоритет этого процесса выше, мический приоритет компилятора. Но первый процесс окируется в ожидании ввода данных. Во время блокиполняется второй процесс. Как только первый процесс разблокирован (введен символ), п л а н и р о в щ и к выполнит ение процессов. Как только введенный символ будет , первый процесс будет заблокирован в ожидании ввода го символа, и снова будет работать компилятор. 137
Некоторые ОС реального времени делают вытесн . только пользовательские процессы. Такое ядро проще пост] так как в этом случае не возникает проблем синхронпзяяп J ядра. Ядро LINUX не относится к такому классу. Так как LI" 1 WINDOWS не относятся к системам реального времени, я процессы ядра могут быть вытеснены наряду с процессам: i вователя. 4 . 3 . 4 . Р е к о м е н д а ц и и п о в ы б о р у к в а н т а времени
От длительности кванта времени существенно зависит т изводительность системы. Если квант времени короткий, СЕТИ слишком часто будет переключать процессы. Эта операции ет много времени, которое в этом случае тратится впустую. ft» если длительность кванта времени равна длительности чт нения операции переключения, 50% времени процессор» М* тратиться на переключение. Если квант времени слишком велик, то долгое нрешьиЯ рирующие процессы будут простаивать, что особенно ы а и в интерактивных процессов. Поэтому квант времени выбирается максимальным, «V обеспечить достаточную реактивность системы для ингерК* ных процессов.
4 . 4 . Процессы, п о т о к и и з а д а н и я Как показано выше, создание нового процесса привод*"»® обходимости выделения памяти под его контекст, а перекладу процессов ведет к необходимости сохраиепия и восстав ав*!» более 100 байтов. Кроме этого, переключение между про с Ж выполняется всегда на 0 уровне привилегий, так как треб1 ключепия задач процессора, а значит, при переключении и чл вательских процессов требуется переход с 3 уровня иркишм на 0, и наоборот. Затруднено такясе использование общих ««ЯШ для процессов в связи с тем, что для каждого процесса шлгт— свое адресное пространство. Поэтому, если необходимо в иЩ приложении создать несколько параллельно выполяягиш» вей, чаще используют тонкие процессы или потоке В некоторых случаях все же используют процессы, мМ могут быть объединены в единое целое. Если необходимо ш 138
"тожения управлять другими приложениями, то используют • к называемые задания. 4.4.1. Процессы
Рассмотрим практическое использование процессов, рабочих в пользовательском режиме, на примере ОС WINDOWS. Есть четыре типа процессов, которые выполняются в польчвательском режиме: постоянные процессы, процессы-службы, тьзовательские процессы (приложения) и подсистемы среды I moment subsystems).
Постоянные процессы — это процессы, которые запускаавтоматически после загрузки системы. Примерами т а к и х трцессов являются процессы регистрации (logon process) и подучена управления сеансом (session manager). Эти процессы не •скаются подсистемой управления службами (service control Л» .ager) — в отличие от всех других процессов. В данном курсе :,ложення этого типа не рассматриваются. Процессы службы. Службы — это особый вид приложения, кюрое выполняет работу для других приложений [4]. Службы пгао запускаются во время запуска ОС, они работают все время, • включен компьютер1. Поэтому при их разработке предъяв"ДЕТСЯ повышенные требования к отказоустойчивости, произвотьности, масштабируемости. Они не связаны с конкретным тьзователем, который регистрируется в системе. Аналогичны 1?.цессам-демонам для ОС UNIX. Наиболее часто они реализуют .лкции сервера. Так как серверы обычно установлены в изорванном помещении, для приложений этого типа необходимо предусмотреть возможность удаленной у с т а н о в к и , з а п у с к а и "ановки (удаленное администрирование). Д л я удаленного администрирования службами используется подсистема управления чтжбами (Service Control Manager — SCM). Поэтому службу жно определить как приложение, управлять которым можно ! помощью SCM. Консоль управления (Microsoft Management I mole — MMC) — универсальная утилита для администрировал (файл ММС.ЕХЕ) позволяет управлять любыми приложениями, в том числе службами. Примеры служб: планировщик (Task Scheduler) — вызов п р и л о ж е н и я в определенный нт времени, инсталлятор (WINDOWS Installer) — управляет ipniMBbie серверы иногда вообще не выключаются.
139
установкой WINDOWS, установкой н удалением програмк И) гие серверные приложения, такие как Microsoft SQL Server, им чают в себя компоненты, которые выполняются как службы Пользовательские процессы (приложения) — оривти приложения, выполняемые с целью решения поставлена! • дачи. Могут быть одного из 4-х типов: Win32. WINDOW--1 MS-DOS, POSIX (OS/21.2). В курсе рассматриваются в р ц ж м типа Win32. Подсистемы среды как раз и позволяют использоватьфув ции POSIX, или OS/2, в приложениях WINDOWS, и BG.V | В данном курсе приложения втого типа не рассматриваются При создании процесса выполняются следующие де1пя Открывается исполнимый файл (.ехе). соответстг**) данному приложению. Это имя определяется из команд кн. которая используется для запуска приложения. Прове] тип приложения. Если это командный файл (имеет расшря bat или cmd), запускается программа cmd. для которого nufd ла-прнложения рассматривается как первый параметр. Вся *| приложение типа WIN32, оно запускается непосредствен»»-„ гие типы приложения в данном курсе не рассматриваются. Создается объект типа «Процесс». Для этого в память для объекта типа «Процесс» EPROCESS в области 1 ядра. Инициализируются поля этой структуры. Вылетят и ресное пространство для процесса в соответствии с данных i мерах сегментов, которые выбираются из исполнимого ф, выполнении любого приложения могут потребоваться по с для выполнения запросов ввода-вывода, выделения памяти, ш хронизации и др. Поэтому для всех процессов, в том чнш < зовательских, создается блок для определения спискядра, необходимых для выполнения приложения (KPRC М Адрес структуры добавляется в конец списка готовых п^ - | Создается начальный поток. До создания потока орн ничего делать не может, так как процессорное время выл » | только потокам. Для потока необходимо задать стек, г** | используется для хранения локальных переменных сот • til раметры потоковой и внутренних функций потока. Тик «в А WINDOWS является вытесняющей ОС, необходимо и память для сохранения восстановления данных при ai потока. Эта область памяти называется контекстом. Рвя ij ка определяется в ЕХЕ-файле для приложения. Поток с-*1и«| в приостановленном режиме, т.е. сразу не запускается. НО
Подсистема WIN32 извещается о создании нового процесса и >ка. Формируется сообщение, в котором передаются дескрипцю созданного процесса и потока. Подсистема W I N 3 2 дублирует я дескрипторы и увеличивает счетчик их использования на 1 М счетчики становятся равными 2, так к а к при их создании они ir навиваются в 1). Если приоритет процесса не задан, он вы•шяется по алгоритму, рассмотренному н и ж е . Создается струкt f j данных о процессе для компонента Csrss. Создается структуt« данных о потоке для компонента Csrss. Адрес этой структуры •""авляется в список потоков процесса. Количество процессов I «сеансеувеличивается на 1. Начинается исполнение начального потока (если не испольг г'яспециальный режим, извещающий о задержке исполнения ЯМка). Оно начинается с заполнения начального состояния конигта.
Выполняется инициализация адресного пространства, задуваются требуемые DLL. Определяется точка входа програмкы, и поток начинает свое выполнение с требуемой команды. Командная строка
При создании нового процесса ему передается к о м а н д н а я -рока. Командная строка содержит: и м я приложения и необязап'ьные параметры. Для определения командной строки д л я прорса можно использовать функцию: PTSTR GetCommandLine ();
Функция возвращает адрес строки с командной строкой, со•жащей полное имя приложения. Переменные окружения С любым процессом ОС связывает переменные о к р у ж е н и я , шять под которые выделена в адресном пространстве процеса. Эти переменные определяют доступные к а т а л о г и д л я приI кення. каталоги для включаемых файлов и библиотек и др. Фшцин API позволяют прочитать и записать новые переменные • ружения, которые действуют на время выполнения данного Одесса.
Для чтения параметров среды используются функции: DWORD GetEnvironmentVariablef LPCTSTR IpName // Имя переменной среды, значение которой •теюся
141
LPTSTR IpBuffer, //Адрес буфера для значения переменно, DWORD nSize //Размер буфера в символах );
Пример. Определить доступные каталоги для текущей qa ложения. #include <windows.h> ttiriclude <stdio.h> #include int mairi(irit argc, char* argv[])
1
DWORD dwSize = GetEnvironmentVariablef "PATH", 0, 0); TBYTE *tbBuffer = new TBYTE[dwSize]; GetEnvironmentVariablef "PATH", (LPSTR)tbBuffer dwSit _putts ((LPCSTR)tbBuffer); return 0;
} Приоритет процесса Каждой задаче присвоен определенный приоритет. Раса трим управление приоритетами на примере WINDOWS. Ты. 1л в WINDOWS к в а н т ы времени выделяются потокам, опред • задание приоритета для потока. Уровень приоритета — от 0 (самый низкий приоритет) .yi i! (самый высокий). Общее количество приоритетов опредет > тем, что д л я задания приоритета используется 32-битное см» один бит соответствует одному уровню приоритета. Приоритет определяется по следующим критериям: — класс приоритета ее процесса; — приоритетный уровень потока внутри приоритетного юс с а процесса. ^^Л Класс приоритета и уровень приоритета комбинируются • формирования базисного приоритета потока. Класс приоритета К а ж д ы й процесс принадлежит одному из следующих п « оритетных классов: IDLE_PRIORITY_ CLA SS NORMAL_PRIORITY_CLASS HIGHPRIORITYCLASS REAL TIME_PRIORITY__CLASS
142
умолчанию, класс приоритета NORMAL_PRIORITY_CLASS. аановки приоритета процесса, отличного от принятого по вию, используется функция CreateProcess. Д л я изменещтета уже созданного процесса используется ф у н к ц и я Class, а для определения текущего уровня — ф у н к ц и я _ toss. Процессы управления монитором, т а к и е к а к screen saveП приложение, которое периодически обновляет дисплей, ы использовать класс приоритета IDLE PRIORITY CLASS. лает задачам данного процесса, не имеющим высокого I) l' "10Л , конкурировать с высокоприоритетными задачами. Приоритет HIGH_PRIORITY_CLASS следует использовать гостью. Если задача выполняется в самом высоком приюм уровне в течение значительного промежутка времени, адачи в системе не будут получать процессорное время, ксколько задач отмечены как высокоприоритетные одноI. теряется их эффективность. Класс с наивысшим придолжен резервироваться для задач, которые д о л ж н ы ъся на критичные во времени события. Если приложение няег одну задачу, требующую первоочередного выполне> -о время как остальные задачи должны иметь нормальный гет, используется функция SetPriorityClass, чтобы измехриоритетный класс приложения временно. После заверкрнтической задачи необходимо привести приоритет к его го по умолчанию. Другая стратегия — создание высокоиого процесса, в котором все задачи заблокированы до как будет необходимо выполнить критическую задачу. ВажI ооы высокоприоритетная задача в ы п о л н я л а с ь к о р о т к и й уток времени, и лишь тогда, когда это необходимо. К .асс приоритета REALTIME PRIORITY CLASS и с п о л ь з у е т -
[ительно для прямого доступа к внешнему устройству. 1аметим, что для работы с приоритетами процесса можно ис1ть только символические константы вместо конкретного приоритета. Установка соответствия между символичеI лстантой и значением приоритета выполняется ОС. Создание процесса
ЕЬувние процесса следует выполнять, если в заданном прип а я необходимо запустить другое п р и л о ж е н и е . Ф у н к ц и я I I "ЙНЙЯ нового процесса CreateProcess имеет очень много цюетров, значения которых могут быть установлены по умол. Полный список параметров приведен в файлах помощи 143
по ф у н к ц и я м WinApi. В д а н н о м п о с о б и и р а с с м а т р и в а е т с я npi I и с п о л ь з о в а н и я ф у н к ц и и CreateProcess. Пример 1. З а п у с т и т ь п р о г р а м м у N o t e P a d . Используя з г щ е н н ы й р е д а к т о р , с о з д а т ь ф а й л D a t a . t x t . П о с л е завершения п р г р а м м ы N o t e P a d в ы в е с т и с о д е р ж и м о е с о з д а н н о г о файла. ttinclude <windows.h> #include <stdio.h> # include int main(int argc, char* argv[]) { STARTUPINFO si; PROCESS_ INFORMATION pi; memset (&si. 0, sizeof (si)); si.cb = sizeof (si); TCHAR tcCommandLine[] = _TEXT("NOTEPAD.EXE DATA.TXT) boolb = CreateProcessfNULL, "NOTEPAD.EXE", NULL, NULL, FALSE, 0, NULL, NULL. &si if(!b){ MessageBox (0, "Error". "Error", MB OK)
} else{
4 //Ждем завершения работы редактора WaitForSingleObject (pi.hProcess, INFINITE) //Определяем код завершения этого процесса DWORD dwRetValue; b = GetExitCodeProcess (pi.hProcess, &dwRetValue) printf ("RetValue = %d\n", dwRetValue); // Освобождаем объект ядра — процесс CloseHandle (pi.hProcess); // Открываем файл для вывода его строк // Он должен быть в текущем каталоге приложении HANDLE h = CreateFile ("DATA.TXT", GENERIC_READ ' : OPEN_EXISTING, FILE ATTRIBUTE NORMAL, 0) if(h == INVALID_HANDLE_VALUE) priritf ("CreateFile:Error\n"); else{ // Определяем размер этого файла DWORD dwLowPart, dwHighPart; dwLowPart = GetFileSize (h, &dwHighPart' // Выделяем память и читаем файл BYTE * buf = new BYTE[dwLowPart]; DWORD dwCount; ReadFile (h, buf. dwLowPart, &dwCount, 0); 144
// Вывод содержимого файла и освобождение памяти printf ("%s\n: but); delete[]buf; //Закрываем файл CloseHandle (h);
} 1
return 0;
Пример 2. Создать «интегрированную среду» для выполнеI -бтер-программ. Программа последовательно выполняет ю, компоновку и отладку ассемблер-программы. Очедг выполняется в случае успешного завершения преды-
ГЧ1) С щ (CommandLine, "C:\\tasm\\bin\\tasm32/ml/zi/I first.asm"); b=CreateProcess (0, CommandLirie, 0, 0, 0, 0, 0, 0, &si, &pi); if('b] printf ("Error\n"); WaitForSmgleObject (pi.hProcess, INFINITE); GetExitCodeProcess (pi.hProcess, &dwExitCodeProcess ); it('dwExitCodeProcess) break; strcpy (CommandLine, "NotePad first.asm"); b=CreateProcess (0, CommandLirie, 0, 0, 0, 0, 0, 0, &si, &pi); if(!bJ printf (' Error %s\ri\ CommandLine); mForSingleObject (pi.hProcess, INFINITE); И М
*rpy (CommandLine, "C:\\tasm\\bin\\tlink32/v first.obj C:\\tasrn\\lib\\ b - CreateProcess (C, CommandLine, 0, 0, 0, 0, 0, 0, &si, &pi); if (Щ printf ("Error\n"); WaitForSingleObject (pi.hProcess, INFINITE); GetExitCodeProcess (pi.hProcess, &dwExitCodeProcess ); if(!tiwEx'itCodeProcess) break; pr.f (CommandLine, "C;\\tasm\\bin\\td32 first.exe"); CreateProcess (0, CommandLine, 0, 0, 0, 0, 0, 0, &si, &pi); i :j printf ("Error\n"); ЦПirSingleObject (pi.hProcess, INFINITE); 145
Завершение процесса П р и завершении процесса ОС выполняет следующи- л-» ствия: — завершается выполнение всех потоков процесса (см. нг*г1 — все объекты, созданные процессом, уничтожаются &Э них вызываются деструкторы), в том числе объекты ядра, «Я они не используются другими процессами. В противном ст>к для объектов ядра уменьшается счетчик использования; — код завершения процесса принимает заданное в функав завершения процесса значение; — объект ядра, соответствующий процессу, переходит в > стояние «Свободно» (Signaled), но не уничтожается до те\ эц пока счетчик списка его пользователей не равен 0. Для прьс.гд тельного освобождения достаточно из процесса, создавшего®! ный процесс, запустить функцию CloseHandle. Есть 3 способа завершения процесса. 1 способ.
Процесс завершается, когда одна из потоковых фупмя! процесса вызывает функцию ExitProcess, которая была рас* трена в первой части курса. Напоминаем, что единственный » раметр функции — код возврата. П р и использовании язык! Сг эту функцию вызывает код стартовой библиотеки после заве»® н и я ф у н к ц и и с и м е н е м main (WiriMain, umain, uWinMain) и ш»
бождения всех ресурсов (стек, «куча» и т.д.). Поэтому в С-»не я в н ы й вызов функции ExitProcess не выполняется. 2 способ. Вызов ф у н к ц и и TerminateProcess. BOOL TerminateProcessf HANDLE hProcess, //handle to the process UINT uExitCode // exit code for the process );
где: hProcess — дескриптор процесса, который должен бып » вершен; uExitCode — код завершения процесса. Эта ф у н к ц и я позволяет з а в е р ш и т ь процесс, для котор«с известен его дескриптор. Недостаток этого способа — сам \э» чтожаемый процесс ничего не знает о своем уничтожении, п " му не может предварительно записать данные на диск, освобазт память, выделенную ему, и т.д. В этом случае ОС освобоад* все ресурсы, с в я з а н н ы е с и с п о л ь з о в а н и е м данного процгга Это асинхронная ф у н к ц и я , т.е. переход на очередную фуотв» 146
ется сразу после вызова ф у н к ц и и T e r m i n a t e P r o c e s s , но до ения процесса. Чтобы гарантировать в ы п о л н е н и е очередлератора только после завершения процесса, необходимо шать функцию WaitForSingleObject {см.. предыдущие при-
пособ. Завершить выполнение всех п о т о к о в п р о ц е с с а , случае код завершения совпадает с кодом з а в е р ш е н и я попотока. Особенности создания, в ы п о л н е н и я и завершеиадков рассмотрены ниже. Информация о процессах, выполняемых в системе
1ля получения информации об и с п о л н я е м ы х п р о ц е с с а х зуется база данных из раздела реестра HKEY_PERFORРКЕ_0АГА. Для доступа к этой базе данных используется набор ЬфшPerformance Data Helper из ( P D H . D L L , T L H E L P 3 2 . H ) .
Фпкции для определения процессов: вОсЕ WiNfiPl Process32First( HANDLE hSnapshot, LPPR0CESSENTRY32 Ippe
POOL WINfi.PI Process32Next( HANDLE hSnapshot, LPPR0CESSENTRY32 Ippe I
h
.PPR0CESSENTRY32 — адрес структуры с информацией о про.pedef struct tagPROCESSE NTRY32 DWORD dwSize;// Размер структуры DWORD cntUsage;//C4em4UK использования DWORD tt)32ProcesslD; II Текущий процесс DWORD th32DefaultHeaplD;//HdeHmu(puKamop кучи по умолчанию DWORD th32ModulelD; /I associated exe DWORD cntThreads; II Количество потоков DWORD th32ParentProcesslD; //Идентификатор // процесса-родителя LONG pcPriClassBase; //Базовый приоритет потоков процесса DWORD dwFlags,//Флаги CHAR szExeFile[MAX_PATH]; // Имя исполнимого файла, который -ответствует процессу PR0CESSENTRY32; 'оограта для определения информации о процессе
147
ft include <windows.h> It include #iriclude <stdio.h> irit main(){ // Определение информации о процессах HANDLE hHelp = CreateToolhelp32Snapshot (TH32CS_S№ROCESS, 0), if (hHelp ==INVALID_HANDLE_VALUE) return 1; //Выделение памяти под структуру с информацией PROCESSENTRY32 ProcessEntry32 = {sizeof (ProcessEntryb BOOL b; // Определение первого процесса b = Process32First(hHelp, &ProcessEntry32 ); while(b){ printf ("cntThreads = %d, ", ProcessEntry32.cntThre& printf ("cntUsage = %d ", ProcessEntry32.cntUsagei priritf ("szExeFile = %s\ri", ProcessEntry32.szExeFn //Для всех остальных процессов b = Process32Next(hHelp, &ProcessEntry32); if (!b) break;
}
return 0;
} В этом примере для каждого процесса выводится количеств потоков, счетчик и и м я исполнимого файла. 4 . 4 . 2 . Задания
Иногда процессы необходимо объединить по какому-то Iзнаку. Например, по общей задаче, которую они решают, -к объединение используется, чтобы м о ж н о было управлять груш"! процессов. Например, при неблагополучном завершении од! 1 из них завершить все остальные процессы этой группы (кони! нер процессов). Такой контейнер в WINDOWS 2000 называла заданием (job). Так как ограничения нельзя задать для обычя. процессов, иногда создают задание, состоящее из одного про» с ограничениями. Ограничения для заданий Д л я задания могут быть установлены ограничения, наг' мер, на длительность процессорного времени, на используете объекты и др. Ограничения бывают разных типов: 148
базовые и расширенные базовые ограничения — не дают факсам монопольно захватывать системные ресурсы; - базовые ограничения по пользовательскому интерфейсу; -ограничения, связанные с защитой. Полная информация о возможных о г р а н и ч е н и я х з а д а н а • toieWINNT.H. Для задания ограничений используются структуры, к а ж д а я I ра определяет ограничения определенного класса. Полная а< рмация о структурах задана в файле W I N N T . H . Пример структуры с общими ограничениями. typedel struct _JOBOBJECT_BASIC_LIMIT_INFORMATION { LARGE INTEGER PerProcessUserTimeLimit; //Время для //одного процесса LARGEJNTEGER PerJobUserTimeLimit; // Время для всех //процессов DWORD LimitFlags; DWORD MinimumWorkingSetSize; //Количество страниц //для процесса DWORD MaximumWorklngSetSize; DWORD ActiveProcessLimit; // Число активных процессов DWORD Affinity;//Процессоры, на которых можно выполнять //процессы OWORD PnorityClass; // Класс приоритета для процесса IOBOBJECT BASIC_LIMIT_INFORMATION;
f
Как видно из этих определений, общие ограничения вклю%вт в себя ограничения на время в ы п о л н е н и я процессором, *}№чения на размер памяти, количество процессоров и уровень :;t ритета.
Ограничения по пользовательскому интерфейсу задаются аряурой: 'tmdef Struct _JOBOBJECT_BASIC_Ut_RESTRICTIONS{ DWORD UlRestrictionsCtass; IJOBOBJECT_BASIC_UI_ RESTRICTIONS, *PJOBOBJECT__ BASIC_UI_RESTRICTIONS;
Этп ограничения включают в себя: невозможность останав; .ьсистему, обращаться к заданному типу объектов и т.д. Конкретные значения ограничений задаются константами, ••мер:
JOB_OBJECT_UIUMIT_EXITWINDOWS — з а п р е щ е н и е к о м а н д
ьгыход из системы, например, ExitWINDOWSEx; 149
JOB_OBJECT_UILIMIT_READCLIPBOARD — запрет чтения а
буфера обмена; JOB_OBJECT_UILIMIT_WRITECLIPBOARD
—
запретит-»
в буфер обмена; JOB
OBJECT
UILIMIT
HANDLES
—
з а п р е т использовали
процессами задания объектов пользователя внешних процессе, таких к а к окна. В поле LimitFlags д о л ж н ы быть заданы классы ограничена!, которые задаются константами: JOBOBJECTLIMITWORKINGSET, JOBOBJECTLIMITPROCESSTIME,...
Ограничения задаются с помощью функции: BOOL SetlnformationJobObject( HANDLE hJob, JOBOBJECTINFOCLASS JobObjectlnformationClass, LPVOID IpJobObjectlreformation, DWORD cbJobObjectlnformationLength);
Эта ф у н к ц и я д л я задания с дескриптором hJob устанаш вает о г р а н и ч е н и я заданного к л а с с а JobObjectlnformationC " используя д л я этого структуру с ограничениями IpJobObjectlnkrmation. Последний параметр определяет размер этой структур* Класс
ограничений
JobObjectlnformationClass принимает зн!ч
ния: JobObjectBasicLimitlnformation — базовые ограничения, зад ю т с я с т р у к т у р о й JOBOBJECT_BASIC_LIMIT_INFORMATION. JobObjectExtendedLimitlnformation — дополнительные базов» о г р а н и ч е н и я , з а д а ю т с я с т р у к т у р о й JOBOBJECT EXTENDED LIMITJNFORMA
TION.
JobObjectBasicUIRestrictions — базовые ограничения по по^
зовательскому интерфейсу, задаются структурой JOBOBJECT BASIC_ULRESTRICTIONS.
JobObjectSecurityLimitlnformation с з а щ и т о й , JOBOBJECT
SECURITY
—
ограничения, связанна»
LIMIT
INFORMATION.
Создание задания Д л я создания объекта типа JOB используется функция: HANDLE CreateJobObject( LPSECURITY_ATTRIBUTES LPCSTR IpName
IpJobAttributes
); 150
Атрибуты безопасности и и м я и с п о л ь з у ю т с я к а к д л я ф у н к MeProcess. Определим о г р а н и ч е н и я д л я з а д а н и я . JCECBJEC ТВА SIC_LIMI J_ IN FORM A TION jobLI; Установим заданные о г р а н и ч е н и я на з а д а н и е ieMomationJobOb/eci( HANDLE hJob, JOBOBJECTINFOCLASS JobObjectlnformationClass, LPVOID IpJobObjectlnformation, DWORD cbJobObjectlnformationLength I;
Завершение всех процессов задания Цлязавершения всех п р о ц е с с о в з а д а н и я и с п о л ь з у е т с я ф у н к BDDL TerminateJobObject (HANDLE h, UINT uExitCode); т а функция з а в е р ш а е т в с е п р о ц е с с ы с к о д о м в о з в р а т а Ше. Статистическая информация о задании Для получения и н ф о р м а ц и и об о г р а н и ч е н и я х з а д а н и я и с ется функция BOOL QuerylnformationJobObject( HANDLE hJob. JOBOBJECTINFOCLASS JobObjectlnformationClass, LPVOID IpJobObjectlnformation, DWORD cbJobObjectlnformationLength. LPDWORD IpReturnLength
В этой функции п а р а м е т р ы к а к в SetlnformationJobObject, •аю последний параметр з а д а е т р а з м е р в ы х о д н о г о б у ф е р а . 1ля получения с т а т и с т и ч е с к о й и н ф о р м а ц и и о з а д а н и и м о ж т тльзовать эту же ф у н к ц и ю , п р и ч е м в к а ч е с т в е в т о р о г о п а рк ia надо задать JobObjectBasicAccountinglnaormation и а д р е с Буры JOBOBJECT_BASIC_ACCOUNTINGJNFORMATION. Ь груктура имеет и н ф о р м а ц и ю : yperfef struct _JOBOBJECT_BASIC_ACCOUNTING_INFORMATION { LARCEJNTECER TotalUserTime; //Процессорное время в режиме //User 151
LARGEJNTEGER TotalKemelTime; // Процессорное врдий / / в режиме Kernel LARGEJNTEGER ThisPeriodTotalUserTime; // Процессорное^» // в режиме User до изменения режима» LARGEJNTEGER ThisPenodTotatKernelTime: //Процессорно» // время в режиме Kerns) //до изменения режимов DWORD TotalPageFaullCount;//Количества ошибок //при обращении к страницаи DWORD TotalProcesses;//Общее количество процессов в зайвм DWORD ActiveProcesses; // Количество активных процессов DWORD TotaiTerminatedProcesses; //Количество зэв-рш // процессов }JOBOBJECT_BASIC_ACCOUNTINGJNFORMATION; Пример программы с заданием
Создать и использовать задание. ttinctude <windows.!» pinclude in t malnfH //Дескриптор задания HANDLE ft Job = CreetBJobObjecl (NULL NULL} //Определение общих ограничений JOBOBJECT_BASIC_LIMIT_INFORMATION jobLI = (sfzeol (pbL i //По приоритету jobLI.PriontyClass = IDLE_PRIORITY„CLASS: //Повремени процессора (1 сек = 10"7 сотней наносекунд) LARGEJNTEGER li: li.QuadPart = 10000000; jobLI. PerJobUserTimeLimit = h\ jobLI.LimitFlags = JOBJDBJECTJIMIT_PRlORlTY_CLASz, JOB_OBJECT_LIMIT_JOBJ~IME, SetlnfcrmationJobObjectfhJob, JobObjectBastcL rnVf &jobLl, s/геоГ (jobLI)); //Определение дополнительных ограничений JDBOBJECT_BASIC_Ut_ RESTRICTIONS]ObUI jobUI. UlRestnctionsCtess ~ JOB^OBJECT_UILMT_NONl I jObUL UIRBstrictionsClass\ =JOB_OBJECT_ U!UMIT_EXITWN№6 jobUI.UIRestnctionsClass\=JOB_OBJECT_UtLIMIT HANDI& SetlnformatbnJobObject(hJob, JobObjectBasicUlReslnc»l% AjobUI sizeof (jobUI)), // Создание процессе и потока в р е ж и м е приостановки STARTUPINFO si = (sizeof (si)): PROCESSJNFORMATION pi; LPSTR IpCommandLine = JEXT(CMDEXE'); J 62
f
CreateProcess (0, IpCommandLine, 0, 0, false, CREATE_SUSPENDED, 0, 0, &si, &pi); Свпзь процесса и задания. Активизация потока <esignProcessToJohObject (hJob, pi.hProcess); ResumeThread (pi.hThread); CloseHandle (pi.hThread);
Ниже более подробно рассмотрена работа с потоками. 4.4.3. Потоки
Потоки используются, если д л я п р и л о ж е н и я можно выдеm отдельные задачи, которые д о л ж н ы в ы п о л н я т ь независи(гиботу. Этн задачи используют общее адресное пространство кения, поэтому для п е р е к л ю ч е н и я потоков необходимо at :аить значительно меньше работы, чем при переключении Поток — объект ядра, т.е. управление потоками выполняет К Напоминаем, что при создании процесса ОС автоматически так называемый первичный поток. Т а к , п р и з а п у с к е р иаммь;, порожденной компилятором с я з ы к а Си и л и С++, • -детый поток выполняет начальный код из библиотеки Си I втекает функцию main, WinMain и л и версии этих ф у н к ц и й IvMCODE(umain, uWinMain). После завершения этих функций • мьиый код вызывает функцию для уничтожения первичного I
ж
В случае использовании потоков ОС выделяет кванты времер ^процессам, а потокам. Каждому потоку соответствует стек, ' т ром помещаются параметры, передаваемые ф у н к ц и я м и по- и.илокальные переменные. Все внешние переменные помещаI i в адресном пространстве процесса, которому принадлежит г»*, поэтому все внешние переменные и объекты ядра, созданw для процесса, доступны всем потокам данного процесса. Это _ ствеино облегчает передачу данных между потоками, но на. «ч определенные ограничения с точки зрения синхронизации -тпа.
Рассмотрим алгоритм создания потоков в пользовательском кении. Этот алгоритм похож на алгоритм создания перл потока, рассмотренный выше, поэтому основные пункты I ритма не комментируются. Шаг 1. Создание стека для потока в адресном пространстве рч«сса. 153
Шаг 2. Выделение п а м я т и под контекст потока. Шаг 3. Создание объекта типа THREAD в приостановленном режиме. Шаг 4. Информирование подсистемы WIN32 о создании но вого потока. Шаг 5. Дескриптор и идентификатор потока возвращаются к а к результаты работы алгоритма. Шаг 6. Поток ставится в очередь готовых потоков. Так как потоки используют существенно меньше системны! ресурсов, чем процессы, то при прочих равных условиях следует использовать потоки, а не процессы. Каждому потоку соответствует своя потоковая функция. Эи ф у н к ц и я запускается при создании потока, если не задано, что OF не должен быть немедленно запущен. Далее определены функции д л я создания и управления истоками для W I N 3 2 . Заголовок потоковой ф у н к ц и и . DWORD ThreadFun (PVOID pvParam){
}
return ...;
Ф у н к ц и и потока, в отличие от функции, соответствующе! первичному потоку, могут иметь разные имена. После заверения потоковой функции завершается соответствующий ей потол. Значение, возвращаемое потоковой функцией, рассматривается к а к код возврата функции. Первичный поток создается при издании процесса, его дескриптор хранится в структуре PROCESS_ INFORMATION. Рассмотрим создание дополнительных ПОТОКСЕ. Создание потока Д л я создания потока используется функция CreateThread: HANDLE CreateThread( LPSECURITY_ATTRIBUTES IpThreadAttributes, //Атрибуты // безопасности DWORD dwStackSize,// Начальный размер стека (байт) LPTHREAD_START_ROUTINE IpStartAddress, //Потоковая //функция LPVOID IpParameter, //Параметр DWORD dwCreationFlags, // Флаги создания LPDWORD IpThreadld // Указатель идентификатора потока );
154
dwStackSize — начальный размер стека, обычно выбирается О, в этом случае ОС назначает его по умолчанию (1 Мбайт ируется и 1 страница закрепляется). IpStartAddres — адрес функции (имя потоковой функции), ько потоков могут использовать одну и ту же потоковую Ьцию. Этой потоковой функции необходимо передавать один Х»отр. Так как значение этого параметра типа LPVOID, это ««быть адрес данных любого типа. Если необходимо передать •гшько параметров, то потоковой ф у н к ц и и передается адрес «туры, куда заносятся требуемые параметры. Прп создании потока ОС устанавливает по умолчанию т а к ишваемыйсчетчик простоев в 1. Это означает, что процессорное pta этому потоку сразу выделяться не будет 1 . П р и выделении шагов времени потокам счетчик простоев у м е н ь ш а е т с я на 1 i: жом цикле выделения. После первого ц и к л а счетчик обнуагя, и процессорное время потоку будет выделяться. В качестве fun создания можно задать флаг CREA TESUSPENDED. В этом : ае поток создается, но кванты времени ему не выделяются ; ,изова функции ResumeThread. Результатом работы функции является идентификатор пост. который записывается по адресу IpThreadld. Если идентифиu,(f потока дальше не используется 2 , этот параметр может быть рвО. Стандартная библиотека языка Си имеет ф у н к ц и и , испольv щие статическую память. Примеры таких функций: rand (), is «торой текущее состояние генератора записывается в статиг ой памяти; strtok, для которой текущий указатель на символ троке находится в статической памяти. Если т а к и е ф у н к ц и и вменяются в многопоточном приложении, то необходимо исr-ыовать специальную библиотеку. Эта библиотека записывает :ш ,е в специальной области памяти, локальной п а м я т и потока. Ди создания потоков в этом случае вместо ф у н к ц и и CreateThread )Гл,льэовать функцию beginthreadex: mtptrj Jbeginthrea dex( void 'security, unsigned stackjsize, unsigned (_stdcall "startjaddress)( void *), ' fen счетчик простоев не равен 0, то потоку процессорное время не выделяется. ,'ju WINDOWS 98 этот параметр не должен быть О!
155
void *arglist, unsigned initflag, unsigned *thrdaddr
); Сравните параметры этой ф у н к ц и и и функции Creafe Thread Вы увидите, что параметры по количеству и длине совпадав' Поэтому очень легко перейти от вызова функции CreateThre к вызову beginthreadex. Д л я того, чтобы подключить библиотек? я з ы к а С++ с поддержкой многопоточности, требуется при созд • нии проекта указать на необходимость поддержки этого режима. Завершение потока При завершении потока ОС выполняет следующие действи" — освобождаются U s e r - о б ъ е к т ы , принадлежащие поты1 (окна и ловушки — hook); — код завершения меняется с STILL_ACTIVE (еще активны i на код завершения функции; — объект ядра Поток переводится в свободное состояние^ е naled); — счетчик использования уменьшается на 1; — если данный поток я в л я е т с я последним потоком процес: > то уничтожается процесс. Объект ядра Поток не освобождает Д л я освобождения памяти, выделенной д л я ядра, использует: < ф у н к ц и я CloseHandle. Можно получить код завершения потока с заданным идентЯ' фикатором. Д л я этого используется ф у н к ц и я GetExitCodeThread Д л я завершения потока можно использовать 4 способа. 1 способ. Поток завершается по завершении потоковойфуа?ции. 2 способ. Для завершения потока используется функция Ext Thread.
3 способ. Один из потоков д л я данного потока вызыв функцию TerminateThread. 4 способ. Завершается процесс, которому принадлежит н ы й поток. 1 способ является наилучшим с точки зрения корректн i освобождения всех ресурсов, п р и н а д л е ж а щ и х потоку. В этом сл> чае корректно вызываются все деструкторы. Освобождается память, занятая стеком потока. Устанавливается код возврата д. данного потока. Счетчик использования для потока уменьшай ся на 1. 156
2 способ корректный с точки зрения ОС, но не С++, т.е. регрсы, которые ОС выделила потоку, будут корректно освобождеJ, счетчик использования будет уменьшен на 1, но деструкторы <штов С++ программы вызваны не будут. Фактически возвратите значение не передается, так к а к после вызова ExitThread •ежа фактически нет. 3 способ фактически эквивалентен 2, но поток, который закутается, об этом ничего не знает, поэтому не может корректно <ыть подготовлен к завершению. 4 способ эквивалентен 3, но завершаются все потоки процесса. Приостановка и возобновление потоков
Поток может запретить для себя выделять кванты времени печение определенного интервала времени. Д л я этого использу[ я функция Sleep: void Sleep (DWORD dwMilliseconds);
f TIE dwMilliseconds — указывает интервал времени в миллисекун" 1 ечение которого ОС не будет выделять кванты времени втоку. Если значение этого параметра равно INFINITE, то поток •шснет» навсегда. Для этих целей лучше использовать функцию вершения потока. Если dwMilliseconds = 0, то поток отказывает остатка текущего кванта времени. Необходимо понимать, во в этом случае система тут же может выделить квант времени гаку же потоку, если нет других потоков в очереди. В оответствии с выбранной политикой п л а н и р о в а н и я ОС •яшяет переключение между потоками (см. 4.3). Д л я протрммного переключения между потоками используется функwBOOL SwitchToThread (). В этом случае ОС проверяет наличие «юка, даже потока с меньшим приоритетом. Если такой поток •Йден в очереди, ему передается очередной квант времени. Если шого потока нет, то возобновляется выполнение первоначальнок потока. ОС возвращает FALSE, если нет ждущего потока. Эта фикция выполняется как функция Sleep при нулевом значении раметра, но в случае функции Sleep управление будет передано | гому потоку только тогда, когда его приоритет выше приориwa в ходного потока. Определение временных интервалов для потоков
Для многозадачной ОС при наличии нескольких процессов, •«дающих своей очереди, переключение между потоками вымнете» ОС. Для оценки вычислительной сложности алгорит«I часто требуется определить время выполнения кода. В этом 157
случае может потребоваться оценить время выполнения поток», вой функции. Использование обычных функций для определения времени тут не годится. В этом случае для определения времг" выполнения можно использовать функцию GetThreadTimes: BOOL GetThreadTimes( HANDLE hThread, LPFILETIME IpCreationTime, LPFILETIME IpExitTime, LPFILETIME IpKernelTime, LPFILETIME IpUserTime );
где: hThread — д е с к р и п т о р п о т о к а ; IpCreationTime — в р е м я с о з д а н и я п о т о к а ;
IpExitTime — время завершения потока; IpKernelTime — время, затраченное ядром на выполнениеп тока; IpUserTime — в р е м я , з а т р а ч е н н о е на выполнение пот( в пользовательском режиме. Д л я з а д а н и я интервалов времени используется тип F LE TIME, который подробно описан в 8.9.2. Этот тип задает колич—7
ство 100 наносекундных интервалов (10 с), которые прош.п с 1.01.1601 года 1 до заданного момента времени. П р и м е р . О п р е д е л и т ь д л и т е л ь н о с т ь выполнения даннг участка кода в пользовательском р е ж и м е и в режиме ядра. #include #include
"stdafx.h" <windows.h>
#include <stdio.h> #using <mscorlib.dll> using namespace System; const DWORD dwCount = 100000000; int x[dwCount]; int_tmain() { ' unsigned int64 i64KernelTime, i64UserTime; FILETIME ftKernelTimeBegin, ftUserTimeBegin, ftNull, ftKernelTimeEnd, ftUserTimeEnd; BOOL bBegin, bEnd; 1
По предположению А. Бушкова, начало письменности следует отнести к этой м
158
bBegin = CetThreadTimes( CetCurrentThread(), HftNull, &ftNull, HftKernelTimeBegin, &ftUserTimeBegin ): //Code for (DWORD i = 0; / < dwCount; i++){ x[i] = i;} bEnd = GetThreadTimesf GetCurrentThreadQ, HftNull, &ftNull, &ftKemelTimeEnd, &ftUserTimeEnd
) if ('bBegin || IbEnd) {
printf ("Error GetThreadTimesW); return 1,
)
else { i64KernelTime = *(unsigned int64*)&ftKernelTimeEnd — '(unsigned int64*)&ftKernelTimeBegin; i64UserTime = *(unsigned int64*)&ftUserTimeEnd — '(unsigned int64*)&ftUserTimeBegin; pnntf("i64KemelTime = %l64d i64UserTime = %l64d\n", i64KemelTime, i64UserTime);
} return 0;
Дм измерения коротких и н т е р в а л о в в р е м е н и , в т е ч е н и е ""та, можно предположить, нет п е р е к л ю ч е н и й м е ж д у п о т о к а и, используется команда RDTSC. Эта к о м а н д а в р е г и с т р а х EDX, Ш возвращает число тактов п р о ц е с с о р а , п р о ш е д ш и х с м о м е н т а к ченпя процессора. Пример. Определить в р е м я в ы п о л н е н и я к о д а д л я в ы ч и с л е |'Якуба целого числа. 159
unsigned
mt64 fun1 (intx, unsigned &z)
{ unsigned int64 i64lnterval; unsigned uLow, uHigh; asm
{
rdtsc mov[uLow], eax mov [uHigh], edx
}
z = x * x * x; asm
{
}
rdtsc sub eax, sbb mov mov
[uLow] edx, [uHigh] [uLow], eax [uHigh], edx
i64lnterval = (((unsigned return i64lnterval;
int64)uHigh)«32) + uLow;
} Заметим, что существуют ф у н к ц и и WinApi для вычислен.; таких величин, но в этом случае затраты, связанные с обращен!1 ем к функции, нельзя не учитывать, поэтому мы рекомевду мв пользовать для таких целей ассемблерные вставки. 4 . 4 . 3 . Контекст п о т о к а
Определяет информацию, которую необходимо сохрангп и восстанавливать при п е р е к л ю ч е н и и потоков 1 . Операцию» хранения и восстановления выполняет ОС. Контекст зависит or архитектуры процессора, который используется. Польза имеет доступ к полям контекста для чтения и записи. Рассмотрю! структуру контекста для архитектуры 1-32 и функции для дст*па к контексту. Контекст состоит из нескольких частей, которые опредог. в табл. 4.1. 1
Перед знакомством с контекстом потока рекомендуем вспомнить ьонтекс цесса, т.е. структуру TSS, определяющую информац IKJ которую необходи хранить и восстановить при переключении процессов.
160
Таблица
4.1
Разделы контекста потока Назначение раздела
Тип раздела
Регистры для хранения целых чисел, в том числе ЕАХ, ЕВХ,
ГЕХТ INTEGERS
ЕСХ, EDX, ESI, EDI
Управляющие регистры, в том числе EIP, EBP, ESP, SegSS,
:WEXT_CONTROL
SegCs, Flags WTEXT SEGMENTS
Сегментные регистры для сегментов данных, в том числе DS, ES, FS, CS
"•.'TEXT FLOATING POINT
Регистры с плавающей точкой
СМЕХТ EXTENDEDREGISTERS Расширенные регистры, в том
числе регистры ММХ
Отладочные регистры
CCHTEXT_DEBUG_REGISTERS
При использовании функций для работы с контекстом не0 чимо указать тип раздела, с которым нужно работать (первая Я юнкатабл. 4.1). Допускается использование нескольких разде, в. В этом случае задается несколько типов и знак | между ними. задания разделов, соответствующих первым трем строкам •if ицы, используется имя CONTEXT FULL. Д л я з а д а н и я всех грок таблицы используется и м я CONTEXT_ALL.
Структура CONTEXT определена в з а г о л о в о ч н о м ф а й л е *. i\T.H. Ниже показан фрагмент этой структуры д л я процессотипа 1-32: typedef struct ^CONTEXT { DWORD ContextFlags; " CONTEXT_DEBUG_ REGISTERS DWORD DrO, Dr1, Dr2, Dr3. Dr6, Dr7; "CONTEXT_FLOATING__POINT. FLOATING_SAVE_AREA FloatSave; HCONTEXT_SEGMENTS. DWORD SegGs, SegFs. SegEs, SegDs; II CONTEXTINTEGER. DWORD Edi. Esi, Ebx, Edx, Ecx, Eax; //CONTEXT CONTROL.
161
DWORD Ebp, Eip, SegCs, EFIags, Esp, SegSs; // CONTEXT_EXTENDED_REGISTERS. BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]: } CONTEXT;
Поле ContextFlags должно быть установлено до использован и я функций для работы с контекстом. В это поле записывается значение типа раздела {см. табл. 4.1). Для чтения раздела контекста используется функция GetThreadContext: BOOL GetThreadContextf HANDLE hThread, LPCONTEXT IpContext );
где: hThread — дескриптор потока, для которого определяется контекст; IpContext — адрес структуры Context. Д л я записи раздела контекста используется функция SeIThreadContext: BOOL SetThreadContextf HANDLE hThread. LPCONTEXT IpContext );
где: hThread — дескриптор потока, д л я которого определяется контекст; IpContext — адрес структуры Context. Заметим, что определять контекст потока имеет смысл из других потоков, причем поток, д л я которого определяется контекст, н у ж н о в н а ч а л е п р и о с т а н о в и т ь {см. функцию SuspendThread). Таким образом, можно управлять не только потоками текущего процесса, но и потоками других процессов. Пример. Создать поток в приостановленном режиме. Определить его контекст. Запустить этот поток. Если поток уже начал выполняться, то приостановить его и восстановить первоначальный контекст. BOOL bThread = false; DWORD WIN API ThreadFun (PVOID) {
162
BOOL bThread = true; for (DWORD i = 0; i < dwCount; i++) { x[i] = i; if (i %10000 == 0) printf ("Thread 2 %d\n", i);
} return 0; rit win() DWORD dwThreadld; HANDLE hThread = CreateThread (0, 0, ThreadFun, 0. О , SdwThreadld); CONTEXT Context; Context.ContextFtags = CONTEXT_ALL; SuspendThread (hThread); GetThreadContext (hThread, &Context); ResumeThread (hThread); tor (i = 0; i < dwCount; i++){ x[ij = i; if(i %2C000 == 0) printf ( Thread 1 %d\ri\ i);
} SuspendThread (hThread); SetThreadContext (hThread, &Context); ResumeThread (hThread); WaitForSingleObject (hThread, INFINITE);
В результате выполнения этого кода сначала запоминается т потока 2, затем этот контекст восстанавливается, и вылл^ние потоковой функции начинается сначала.
4.5. Вопросы и з а д а ч и I В каком случае в программе создается новый процесс? . В каком случае в программе создается новый поток? J. В каком случае используется задание? I. Какая функция позволяет дождаться естественного завершения процесса? 163
5. 6. 7.
Какие еще способы завершения вы знаете? Дайте характе; : т» ку каждой функции. Как узнать код завершения процесса? Какой код обычно (ответствует нормальному завершению? Какая функция используется для создания потока? В к.ш « случае для этих целей нельзя использовать функцию СлмЬ Thread?
8.
Что такое потоковая функция, чем она отличается от обьгк.1 функций, какой заголовок должна иметь? 9. Может ли нескольким потокам соответствовать одна потоки функция, может ли потоку соответствовать несколько гкош вых функций? 10. Что такое контекст потока? Каким образом его можво ислош» вать в программе? 11. Составьте программу, которая вызывает текстовый реавюц WinWord, создает файл, проверяет его размер и, если разлн а» данного файла больше 20 Кбайт, вызывает программу для чм вирования этого файла (например, WinRar), вызывает прогр«л му для отправки сообщения (например, OUTLOOK) и отправ"»* созданный файл или архив как прикрепленный файл.
5. ОБЗОР СРЕДСТВ С И Н Х Р О Н И З А Ц И И ПОТОКОВ И ПРОЦЕССОВ ДЛЯ ОС W I N D O W S
Выше рассмотрены назначение, приемы и методы синхро• пии. которые используются в различных ОС. В этом разделе ta,; рассмотрены средства синхронизации потоков и процессов d ОС WINDOWS. Объект синхронизации должен хранить информацию, доступцл "я процессов, работа которых синхронизируется. Процессы независимые адресные пространства, которые никогда к кгсекаются. Для хранения общих объектов используется ...та ядра, доступная всем процессам. В этом случае к а ж д а я •ршв синхронизации требует переключения из р е ж и м а польщен в режим ядра, и наоборот, что является вычислительно » мй операцией. Поэтому операция синхронизации д л я проr^-t выполняется только в случае ее необходимости, количеasu мких операций нужно минимизировать. П'токи процесса используют одно и то же адресное пространр в этому объекты синхронизации для потоков могут и обычно t;. iii *ч в адресном пространстве потоков, но д л я блокирования га все равно требуется переключение в р е ж и м ядра. Таким 4^-1 и, потери времени будут тем больше, чем чаще потоку не' двмо ждать освобождения ресурсов. Поэтому вероятность ||мревия к занятому ресурсу следует максимально уменьшать I?: ;тгмическими средствами. Ранее было показано, что даже отдельная команда процеси может быть прервана (см. 3.2). Поэтому современные ОС | :• иют средства для атомарного доступа к д а н н ы м текущего щ "та. Нпже рассмотрены средства синхронизации, начиная 165
с самых простых — атомарного доступа и кончая средствами ск хронизации для процессов, предоставляемые ОС WINDOWS.
5 . 1 . С и н х р о н и з а ц и я потоков. Атомарный доступ Д л я атомарного доступа используется специальный ми Interlocked функций. Эти функции позволяют, например: — изменить значение переменной, заданной своим .иреси на заданную величину; — обменять значения двух переменных, заданных с» адресами; — проверить значение переменной и изменить еговзалччпш случае. Адреса всех переменных, которые задаются в функции Ж го класса, должны быть выровнены на границу 32-битного сдщ т.е. быть кратными 4. Д л я переменных, объявленных в яю» С++, это гарантируется. Будьте внимательны при испольэоваял кода, пример которого приведен ниже: DWORD а; BYTE ЬМет[10]; DWORD *pdwMem = ЬМет + 3;
В этом случае адрес, записанный в pdwMem, не будет нес ным 4, поэтому его нельзя использовать как адрес в фуяга класса Interlock. Это связано с тем, что доступ к таким перемен*» не может быть выполнен за один такт, поэтому функция не ж «г быть примитивной. Д л я указателей функций этого класса задается слово кЛ которое означает, что значение этой переменной нельзя бра'1.» кэша, оно должно сразу обновляться. Это делается для тог бы в многопроцессорных системах всегда работать с ахтугмШ значением переменной. Рассмотрим примеры этих функций. 1. Д л я присвоения заданного значения переменной (*: в режиме эксклюзивного доступа используется функция 1гШ ckedExchange: LONG InterlockedExchangef LONG volatile* Target, LONG Value
); 166
Targe! — Переменная, значение которой изменяется; Value —Значение, которое присваивается. Рассмотрим реализацию этой функции на ассемблере 1 . I В этой функции для исключения л и ш н и х команд регистр Лее используется, доступ к параметрам в ы п о л н я е т с я через bvrpesp. Ш6АСЗ mov ecx.dword ptr [esp+4]; 'ШАС7 mov edx.dword ptr [esp+8]; 'ШАСВ mov eax,dword ptr [ecx]; ПЕ86АСО lock cmpxchg dword ptr [ecx],edx; Ш6 AD1 jne 77E86ACD
ecx = Target edx = Value еах = *Target while (eax !=[ecx]); [ecx]=edx
Ш6ЛОЗ ret 8 Префикс lock в команде cmpxchg обеспечивает выполнение •южной команды без прерывания, р использования функции: ma tile LONG IVar = 0; "WlockedExchange (&IVar, 1); //IVar = 1;
l Для изменения значения переменной на постоянную вег (х += а) в режиме эксклюзивного доступа используется цля InterlockedExchangeAdd: LONG IntertockeOExchangeAddf LPLONG volatile Addend, LONG Value
Функция увеличивает значение переменной Addend, д л я • ой передается адрес, на величину Value, для которой переся зиячение. Как следует из типа Value, оно может быть к а к so .{штельным, так и отрицательным. Пример использования функции: «ladle LONG IVar = 0; Ж Value = 5; 'ierlcckedExchangeAdd (&IVar, Value); //IVar += Value;
3. Для присвоения переменной значения другой переменной ,) используется функция InterlockedExchangePointer: l:i учения реализации функции в среде Visual Studio нужно дойти в от-ii "1 необходимой функции, выбрать View->DebugWINDOWS->Disassemby I ч и п функции с помощью функциональной клавиши F11. Получим асв р а ш код функции. Для покомандного выполнения этого кода использует..Г
167
-.очистка стека
PVOID InterlockedExchangePointerf PVOID volatile* Target, PVOID Value );
В этой функции оба параметра являются адресами перемя ных, исходной (Value) и результата (Target). Пример использования функции: volatile LONG IVar = 0; LONG Value = 5; lnterlockedExchangePointer( &IVar, &Value); Функция InterlockedCompareExchange LONG lnterlockedCornpareExchange( LONG volatile* Destination, LONG Exchange, LONG Comperand );
Ф у н к ц и я сравнивает значения Destination и Comperand. Б л Destination
==
Comperand, то з н а ч е н и е Exchange запиеы
- I
в Destination, в противном случае значение Destination не пзл-^ ется. Рассмотренные в ы ш е ф у н к ц и и всегда необходимо пев зовать в потоках, если требуется монопольный доступ к перем ной, значение которой должно измениться! Пример. Составить программу для чтения файлов с \ к» выми данными и суммирования значений всех элементов файлов. 1 способ. Последовательное чтение данных из файлов i i суммирование. В этом случае общее время решения задачи с у м м а р н о м у в р е м е н и , необходимому д л я обработки каждо файла. 2 способ. К а ж д ы й файл читается в отдельном потоке. С\ ш формируется в переменной, доступной всем по токам. Так к а к операции чтения данных из файлов в этом с-л могут выполняться параллельно, общее время решения может быть уменьшено. Поэтому рассмотрим решение В1&р» способом. Операцию и з м е н е н и я переменной для суммы выполнять с помощью ф у н к ц и и InterlockedExchangeAdd, та" w в противном случае возможна ошибка (почему?). Программа для второго способа. 168
•hide <windows.h> • lude<stdio.h> mgmahdrstop .MGISurn-O; WORD WINAPI ReadAndSum (PVOID pName) LPSTRIpName = (LPSTR)pName; RLE Y=fopen (IpName,"rt"); if (f==0) return 1; DWORD dwNumber; inti: for(i=0; /'++) I if(i%100==0) printf ("%s\n", IpNarne); if (fscant (f, "%d'\ &dwNumber)== -1) break; //ISum += dwNurnber; IntertockedExchangeAc!d(&ISum, dwNumber);
} fclose (f); return 0; = Mine NUMBERS 10000 mainfmf argc, char* argv[]) RLE *f= fopen ("C:\\TMP\\Numbers.txt", "wt"); M
I
phntff'Create File %s Error ", "C:\\TMP\\Numbers.txt"); return 1;
I intij=1: for(i-0; i < NUMBERS; i++) fprintfff, "%d ", j); fclose (f); f= fopen ("D;\\TMP\\Nurnbers.txt", "wt"); M
I
)
printf ('Create File %s Error", "D:\\TMP\\Numbers.txt"); return 1;
f-2; for (i=0; i < NUMBERS; /'++ ) fprintf(f. "%d ". j); fclose (f); DWORD Threadld; 169
HANDLE h[2]; for (i = 0; i < 10; /++)
{ ISum = 0; h[0] = CreateThread (0, 0, ReadAndSum, 'С WTMP k mbers.txt,0, &Threadld); h[1] = CreateThread (0, 0, ReadAndSum 'D! TMP mbers.txt",0, &Threadld); WaitForMultipleObjects (2, h, true, INFINITE) printf(" ISum = %d\n", ISum) CloseHandle (h[OJ); CloseHandle (h[1]);
}
return 0;
} В этом примере формируются два файла с числами, со„ , мое которых читается отдельными потоками. Для суммирс-'Ш чисел используется функция InterlockedExchangeAdd. Закомм « тированный оператор ISum += dwNumber является потенци опасным, так как может быть прерван после загрузки тег значения суммы в регистр, что приведет к ошибке вычис-л! И хотя вероятность прерывания потока именно в этом месте <" вероятна, при программировании нельзя ее не учитывать.
5 . 2 . С и н х р о н и з а ц и я потоков. Критическая секцм InterLock функции позволяют в монопольном режиме и полнить только элементарные операции. Если необходимо! нить группу операций в монопольном режиме, эти операци' v единяются в критическую секцию. Напоминаем, что критич >-1 секцией называют участки потоковых функций, которые ] прервать для выполнения такой же критической секции др т потоковых функций данного процесса. Обращаем вниманЯ' Л не вообще нельзя прервать, а нельзя прервать для вытг заданной критической секции другого потока. В потоковой ф • ции можно использовать несколько критических секций. С «» дой критической секцией связывается ресурс, доступ к ко • защищает эта критическая секция, например, в качестве pi Щ можно использовать файл, одновременный доступ к котороыт» прещен. Запрет на одновременное исполнение распростри только для данной критической секции, т.е. возможно, что .. 170
«ьшолняет код критической секции 1, второй — код крити•Икщш 2 и т.д. ?ля использования критической секции необходимо выполданедующие действия. 1. Выделить память под критическую секцию т а к и м обра•а -тбы эта структура была доступна всем потоковым функциI тгсрые используют эту критическую секцию: CRITICALJECTION cs;
! До создания потоков, использующих к р и т и ч е с к у ю секши, инициализировать ее (функция InitializeCriticalSection): fniMialiieCriticalSection(LPCRITlCAL SECTION IpCriticalSection);
tbtica/Section — адрес структуры типа CRITICALSECTION. I том случае ОС формирует поля структуры таким образом, казать, что критическая секция свободна. 1 Определить начало критического участка потоковой функз " "омощью функции EnterCriticalSection-. fOID EnterCriticalSection (LPCRITICAL_SECTION IpCriticalSection); *tCnticalSection — адрес структуры типа CRITICALSECTION. |iwviy4ae проверяется поле занятости критической секции, .»• :и она свободна, то значение флага з а н я т о с т и м е н я е т с я гсояние «Занято» и продолжается выполнение программы, (дошью какой функции можно в ы п о л н и т ь эту проверку? In критическая секция занята, то д л я блокирования потока VI лияется переключение в режим ядра. Поток блокируется Г> ,'Вобождешш ресурса. Если необходимо проверить, можно 11 _т 1 в критическую секцию, используется ф у н к ц и я TryEriterB(WSecl/on.
BOOL TryEnterCriticalSection( LPCRITICALJECTION IpCriticalSection
jt CriticdISectiOfi — адрес структуры типа CRITICAL_SECTION. 5 а вход в критическую секцию возможен, то ф у н к ц и я возврапг TRUE и выполнится как функция EnterCritica/Section, если нещр кен. то функция возвращает FALSE. 4. Определить конец критической секции участка потоковой jinc помощью функции LeaveCriticalSection: VOID LeaveCriticalSectionf LPCRITICA L_SECTlON IpCriticalSection); 'pCnticalSection
— адрес структуры типа 171
CRITICAL
SECTION.
По этой ф у н к ц и и флаг занятости ресурса устанавливает в состояние «Свободно», потоки, которые ожидали освобождены этого ресурса, разблокируются. 5. В основном потоке, в котором выполнялась инициал» ц и я критической секции, удалить критическую секцию, ног» она больше не н у ж н а ( ф у н к ц и я DeleteCriticalSection). VOID DeleteCriticalSection (LPCRITICAL_SECTION IpCriticalSecW
где IpCriticalSection — адрес с т р у к т у р ы т и п а CRITICAL SECTION
При завершении процесса критическая секция удаляется а»томатически. Если для критической секции выполнено удалеяв, то использовать ф у н к ц и ю EnterCriticalSection для этого рестра нельзя. Пример. Пусть 2 потока пишут записи в файл. Записи структуру. Номер потока, номер записи для этого потока. Е"Я один поток начал писать запись в файл, то до завершения эгЛ записи другой поток писать в файл не может. Пусть номер пет и передается в списке параметров потоковой функции. Uinclude <windows.h> tfinclude <stdio.h> Uindude <string.h> HANDLE hFile; CRITICAL SECTION cs; DWORD WINAPI ThreadFun (PVOID pvPar) { DWORD dwCount; int ThreadNumber = *(int*)pvPar; char cRecord[256] = (0); DWORD dwLen; for (int i = 0; i < 10; i++)
{
}
for (intj = 0;j < 1000000; j++); sprintf (cRecord, "Thread # %d Record # = %d\r\r: ThreadNumber, i); dwLen = strlen (cRecord); cRecord[dwLen] = 0; EnterCriticalSection (&cs); WriteFile (hFile, cRecord, dwLen, &dwCount, 0); LeaveCriticalSection (&cs);
return i;
}
int mainQ { DWORD dwParl = 1, dwPar2 = 2;
172
HANDLE hThread[2J; (Fife = Createfi/e ("Log.txt" GENERIC WRITE, FILE SHARE READ, 0, CREATE_ALWAYS, 0, 0); • Ш == INVALID HANDLE VALUE) return 1; DWORD dwldent; '-MizeCriticalSection (Acs); iJlread[0] = CreateThread (0, 0, ThreadFun, &dwPar1, 0, &dwldent); hThreed[lj = CreateThread (0, 0, ThreadFun, &dwPar2, 0 &dwldent); * (hThread[0] == INVALID HANDLE_VALUE || №iread[1] == INVALID HANDLE_VALUE) { CloseHandle (hFile); return 1; №For'MtipleObjects (2, hThread, true, INFINITE); C.oseHardle (hThread[Oj); CloseHandle (hThread[1]); CloseHandle (hFile); return C-
Пример результата: Thread # 1 Record # = 0 Thread # 2 Record # = 0 Thread # 2 Record # = 1 iread # 1 Record # = 1 Thread* 1 Record # = 2 "'iread # 2 Record # = 2 Tmd # 2 Record # = 3 Thread # 1 Record # = 3 Thread* 1 Record # = 4 ri.read # 2 Record # = 4 Thread # 2 Record # = 5 TLread # 2 Record # = 6 I i.-ead # 2 Record # = 7 Thread # 2 Record # = 8 Thread # 2 Record # = 9 Thread #1 Record # = 5 Tfcread # 1 Record # = 6 Thread # 1 Record # = 7 Thread # 1 Record # = 8 bread # 1 Record # = 9 Фрагмент программы for (int j - 0; j < 1000000; J++); потребо-
ядлятого, чтобы время выполнения потоковой функции презрительность одного такта, в противном случае потоки 173
выполняются строго последовательно. Обратите внимание иая что к р и т и ч е с к а я с е к ц и я з а н и м а е т с я только на момент запк.1 в файл. Рекомендуется освобождать критическую секцию, ш только она больше не н у ж н а . Ф у н к ц и я WaitForMultipleObjedsn пользуется для о ж и д а н и я завершения созданных потоков. Ф^а ции Wait... будут рассмотрены н и ж е . Рассмотрим особенности использования нескольких крип ческих секций в одном потоке. Пусть к а ж д ы й поток пишет зама сначала в свой файл, а потом в чужой. В этом случае можно к пользовать общую критическую секцию, которая формирует о& записи в файлах, но при этом длительность выполнения критик ской секции велика, т.е. о ж и д а ю щ и й поток блокируется н#дя1 Д л я уменьшения времени блокирования введем 2 критически секции по одной на к а ж д ы й файл. В этом случае д л я первой потоковой функции имеем: EnterCriticalSection(cs1); Запись в файл1; LeaveCriticalSection (и,' EnterCriticalSection(cs2); Запись в файл2; LeaveCriticalSection (csi,
Д л я второй потоковой ф у н к ц и и имеем: EnterCriticalSection (cs2); Запись в файл2; LeaveCriticalSection ДО EnterCriticalSection (cs1); Запись в файл1; LeaveCriticalSection /Of
При использовании нескольких критических секций нео*д» димо избегать вариантов, когда критические секции вложевы. i области их действия пересекаются (рис. 4.1). Поток 1
Поток 2
EnterCriticalSection (cs1);
EnterCriticalSection(cs2l
EnterCriticalSection (cs2);
EnterCriticalSection(cs1
LeaveCriticalSection (cs1);
LeaveCriticalSectbn (cs2\
LeaveCriticalSection (cs2);
LeaveCriticalSection (cs1i
В этом случае потоки блокируют друг друга, если нервы! а ток захватил критическую секцию cs1 и не успел захватить!* а поток 2 захватил cs2 и не успел захватить cs 1. Тогда вторая г? ка операторов для обоих потоков никогда не может быть выао нена. Д л я решения этой проблемы можно начать работу с др-п! 174
утеской секцией только после завершения работы с первой J захватывать эти критические секции в одинаковом порядке I "боих потоков.
5.3. Использование объектов ядра для синхронизации 5.3.1. Общая характеристика объектов
Объекты ядра создаются в области п а м я т и ядра, поэтому I объекты доступны для разных процессов. Вот почему, если я гинхронпзации используются объекты ядра, то их м о ж н о отменять не только для синхронизации потоков, но и процесв. Недостатком всех способов, основанных на использовании Лектов ядра, является необходимость п е р е к л ю ч е н и я м е ж д у эс ьзовательским режимом и режимом ядра д л я работы с объекззтому быстродействие этих методов меньше, чем методов, ^•смотренных выше. Объект ядра может находиться в свободном » ятом состоянии. Понятия свободного (signaled state) и заня• inorsignaled state) состояний зависят от конкретного объекта. Ь риыер, поток занят до тех пор, пока выполняется его потокои футадя; процесс занят, пока выполняется хотя бы один его Я >к; файл занят, пока для него не выполнена операция ClosetUtme.
Еслп необходимо использовать один и тот же объект синхроИ дня в разных процессах, этому объекту присваивается имя, а доезадается в функции создания объекта. Таким образом, все г> -..цпи создания объектов синхронизации имеют такой общий и • Create06beKm (Дескриптор безопасности, ..., И м я объекта). В качестве объектов синхронизации используются следуюW
События (Evenf) — наиболее простые в управлении, могут пользоваться для организации критических секций, в качестве и ячныхсемафоров, для асинхронного ввода-вывода (см. ниже); Мьютексы (Mutex) — используются для организации крити-чих секций в процессах; Семафоры (Semaphore) — используются для синхронизации I ,-ide, если имеется заданное количество однородных ресурсов; Ждущие таймеры (Waitable Timer) — используются д л я синЦ№ щии с учетом абсолютного времени или временных интер)В.
175
5 . 3 . 2 . Ф у н к ц и и ожидания (Wait-функции)
Ранее у ж е и с п о л ь з о в а л и с ь ф у н к ц и и WaitForSingleOb)-* WaitForMultipleObjects для о ж и д а н и я , пока будут завершены nj< цесс или поток. Здесь мы более подробно рассмотрим этот ДОЦ функций, потому что именно они используются для синхрон! •• ции с помощью различных объектов ядра. Эти функции прио~" навливают (блокируют) поток до тех пор, пока не случится ол» или несколько событий. Р а с с м о т р и м более подробно а л г о р и т м выполнения этс класса функций. Д л я каждого объекта ядра, в том числе File, Process, Thread объектов синхронизации задаются состояние этого объекта (^у бодный или занятый) и список потоков, которые ждут осв( дения этого объекта, если объект занят. Таким образом, ОС яеш может определить, к а к и е потоки зависят от данного объекта. К а ж д ы й заблокированный поток имеет список объектов, № торые д о л ж н ы освободиться д л я продолжения его работы. При освобождении объекта ОС корректируется его соето* ние. Выбирается очередной поток, ж д у щ и й данный объект. Ее-.: этот поток не зависит от других объектов, его состояние изменяет ся. Если это поток с динамическим приоритетом, устанавлявновое значение приоритета. Если исполняемый в данный ыом и поток имеет приоритет меньший, чем приоритет нового пс: м исполняемый поток заменяется новым. В противном случа I вый поток переводится в состояние «Готов» и ставится в очере:готовых потоков. В любом случае вносятся необходимые кор ции в очереди объекта и потока. 1. Ф у н к ц и я WaitForSingleObject: DWORD WaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds );
где: hHandle •— дескриптор объекта ядра, который может наидиться в состоянии «свободен» и «занят»; DwMilliseconds — интервал времени в миллисекундах, в Tf ir ние которого необходимо ждать освобождения заданного объе i Если вместо этого параметра задано INFINITE — ожидание г тко, сколько нужно. Возвращаемое значение: WAIT_OBJECT_0— ф у н к ц и я завершена, так как заданобъект перешел в состояние «Свободен»; 176
WAlT_TlMEOUT - функция завершена, т а к к а к истек заданЯЙ интервал времени. 2. Функция WaitForMultipleObjects. DWORD V a tForMultipleObjects ( DWORD nCount, CONST HANDLE *IpHandles,
BOOL bWa tAII DWORD dwMilliseconds )•
Ш "Count — количество дескрипторов, состояние которых прогся; IpHandles — массив дескрипторов, состояние которых прогся: bWailAII — флаг ожидания; если флаг равен TRUE, то функV ждет освобождения всех объектов, если FALSE — то ф у н к ц и я освобождения хотя бы одного объекта; DwMilli econds — интервал времени в миллисекундах, в те»°ie которого необходимо ждать освобождения заданных объелся. Если вместо этого параметра задано INFINITE — ожидание яотько, сколько нужно. Возвращаемое значение: WAIT_OBJECT_0,
WAITOBJECT1,
...
— функция
заверше-
и.т«скак объект с заданным номером перешел в состояние «Сво4мк* (если bWaitA/l = FALSE);
WAIT TlMEOUT— функция завершена, так к а к истек заданш! интервал времени. Примеры использования этих ф у н к ц и й р а с с м а т р и в а л и с ь Шве (сл. 5.2) и будут рассмотрены ниже д л я конкретных объекIM инхронизации. 5.3.3. События (Event)
Используется в том случае, если надо «вручную» управлять •стоянием, которое, может быть свободным и занятым, и выполШьгаданные действия в зависимости от этого состояния. Рассмотрим алгоритм обработки событий ОС. Пусть пользовательский поток ждет, пока заданное событие •рйдет в свободное состояние (Signaled). В программе использу•сяфункция WaitForSingleObject с дескриптором события. Ядро изменяет состояние этого потока из состояния «Готово» 1'остояние «Ожидание» и помещает данный поток в очередь по1Няв, ждущих данное событие. 177
Пусть другой поток установил заданное событие в свобо: состояние. Ядро анализирует очередь потоков, ждущих заданное гтб*тие. Если есть ж д у щ и й поток, оно изменяет состояние этоп тока из состояния «Ожидание» в состояние «Готов». Если данви поток имеет д и н а м и ч е с к и й п р и о р и т е т , приоритет этого пот м изменяется. Т а к к а к п о я в и л с я новый готовый поток, диспетчер поте • проверяет необходимость передачи к в а н т а времени потоку, и м е н я в ш е м у свое состояние. Е с л и исполняемый поток имеет оритет н и ж е , чем н о в ы й поток, он заменяется новым пот к если нет потока, к о т о р ы й м о ж е т быть заменен, то готовый пЯ» ставится в очередь готовых потоков. Рассмотрим ф у н к ц и и д л я создания и использования собь.. 1. Создание события. Ф у н к ц и я CreateEvent. HANDLE CreateEvent ( LPSECURITY_ATTRIBUTES IpEventAttributes, BOOL bManualReset, BOOL blnitialState, LPCTSTR IpName).
где: IpEventAttributes — атрибут безопасности (у нас 0); bManualReset1 — п р и з н а к у п р а в л е н и я вручную; blnitialState — начальное состояние события; IpName — и м я события. Ф у н к ц и я возвращает д е с к р и п т о р объекта. В случае оши возвращает О. 2. Установка свободного т е к у щ е г о состояния. BOOL SetEvent(
HANDLE hEvent ),
где hEvent — д е с к р и п т о р события. 3. Установка занятого т е к у щ е г о состояния. BOOL ResetEvent(
HANDLE hEvent );
где hEvent — дескриптор события. 4. Освобождение объекта я д р а — ф у н к ц и я CloseHandle Пример. Создать п р о г р а м м ы д л я чтения и записи Программа д л я ч т е н и я ф а й л а д о л ж н а выполнять чтение Если равно TRUE, то состояние надо устанавливать вручную.
178
| :учае, если предварительно в ф а й л ч т о - т о п и с а л и . П р о г р а м осн должна писать в ф а й л т о л ь к о в т о м с л у ч а е , е с л и р а н е е к • даш запись была прочитана. Для решения этой з а д а ч и б у д е м и с п о л ь з о в а т ь 2 с о б ы т и я : tf- Ше — событие разрешает п и с а т ь в ф а й л . У с т а н а в л и в а е т с я ItfТ'Яние «Свободно», когда м о ж н о п и с а т ь , н а ч а л ь н о е с о с т о я т- свободно. hEventRead— у с т а н а в л и в а е т с я в с о с т о я н и е «Сво'•••», когда можно читать, н а ч а л ь н о е с о с т о я н и е — з а н я т о . Процесс для чтения файла. «elude <-wirdows h> : кЫв •4 main ()( HANDLE hFile; IIЕсли файла нет. то отказываемся от кванта времени while (1){ hFile = CreateFile ("..WMyFile.txt" GENERIC READ, FILESHAREREAD, 0, OPEN EXISTING, О, 0); if(hFile==INVALID_HANDLE_VALUE) Sleep (0); else break;
} Открытие объекта MyEventRead HANDLE hEventRead = CreateEventfO, false, false, "MyEventRead"); I HEventRead == 0) throw ("Error CreateEventRead\n"); Открытие объекта MyEventWrite KANDLE hEventWrite = CreateEventfO, false, true, "MyEventWrite"); i'hEventWnte -= 0) throw ("Error CreateEventWrite\n"); harbuffer(20]; DWORD count; film чтения записи файла k itti=0; ;i++){ for (int j=0;j<100000; j++);// Задержка cout«"r"; WaitForSingleObject (hEventRead, INFINITE); ResetEvent(hEventWrite); ReadFile (hFile, buffer, 12, &count, 0 ); buffer[12]=0; if (!count)break; cout« buffer «'In'; SetEvent (hEventWrite);
}
return 0;
179
Процесс записи в файл #include <windows.h> #include int main(){ HANDLE hFile, try{ cout« "Write..An"; hFile = CreateFile ("..\\MyFile.txt", GENERICWRITE FILE_SHARE_READ, 0, CREATE_ALWAYS. , > if (hFile==INVALID_HANDLE_VALUE) throw (Error С I File"); HANDLE hEventRead = CreateEvent(0, false, false. "MyEventRead"); if (hEventRead == 0) throw ("Error CreateEventRead\n"); HANDLE hEventWrite = CreateEvent(0. false, true, "MyEventWrite"); if (hEventRead == 0) throw ("Error CreateEventWrite\n"); char buffer[20]="aaaaaaaaaa\r\n"; DWORD count; for (int i = 0; i < 1000; i++){ for (int j = 0; j<100000; j++); cout«"w"; WaitForSingleObject (hEventWrite, INFINITE ResetEvent(hEventRead); WriteFile (hFile, buffer, 12, &count, 0); SetEvent (hEventRead); //Sleep(O);
}
}
catch(char *msg){ cout « msg « 'In';
}
return 0;
Управляющий процесс. ttinclude <windows.h> #include 180
Verain(){ hy{ HANDLE hEventRead = CreateEventfO, true, false, "MyEventRead"); if (hEventRead == 0) throw ("Error CreateEventRead\n"); HANDLE hEventWrite = CreateEventfO, true, true, "MyEventWrite"); if (hEventRead == 0) throw ("Error CreateEventWriteW); STARTUPINFO si[2]; memset (&si[0], 0, sizeof (si[0])); siJOJ.cb = sizeof (si[OJ); memset (&si[1], 0, sizeof (si[1])); si[1].cb = sizeof (si[1]); PROCESS_ INFORMATION pi[2]; BOOLb = CreateProcess(0, ".-WreadWread.exe", 0, 0, false, 0, 0,0, &si[0], &pi[0] ); if(!b)throw ('Error CreateProcess Read\n"); BOOLb = CreateProcess(0, "..WwriteW write.exe", 0, 0, false, 0, 0,0, &si[0], &pi[0] У. if(tb)throw ("Error CreateProcess Write\n"); HANDLE hProcesses[2]; hProcesses[0] = pi[0].hProcess; hProcesses[1] = pi[1].hProcess; WaitForMultipleObjects (2, hProcesses, true, INFINITE); CloseHandle (pi[0].hProcess); CloseHandle (pi[1].hProcess);
} catch (char "Err){ cout« Err;
}
return 0;
5.3.4. Мьютекс Мьютекс используется д л я :
- организации критической секции д л я процессов 1 ; - проверки повторного запуска запущенного процесса. Гчздание(открытие) м ь ю т е к с а . Ф у н к ц и я CreateMutex. MNDL£ CreateMutex( lPSECURITY_ATTRIBUTES IpMutexAttributes, BOOL btnibalOwner LPCTSTR IpName
nrпользовать и для критических секций потоков, но это менее эффективf -альзомние CRITICAL SECTION.
181
где: IpMutexAttributes — атрибут безопасности, у нас равен 0; blnitialOwner — определяет р е ж и м использования мьюи • (рассмотрен ниже); IpName — и м я мьютекса, используется для ссылки на негм и других процессов. Рассмотрим более подробно р е ж и м ы использования мм» текса. Если параметр blnitialOwner равен TRUE, то мьютексус д* присваивается занятое состояние, причем он считается заняты потоком, который создал этот мьютекс. Это значение имеетCMbi использовать, если поток, создающий мьютекс, должен выш i н я т ь к р и т и ч е с к у ю с е к ц и ю п е р в ы м . Если этот параметр рав-" FALSE, мьютекс при создании считается незанятым. Чтобы 11 стал занятым, используется одна из функций ожидания, кс- м проверяет его состояние и устанавливает в состояние «Занят • если он был свободен. Это значение параметра используется,е( п все потоки, которые используют мьютекс, равноправны с точ; I зрения порядка выполнения критической секции. Освобождение мьютекса. Ф у н к ц и я ReleaseMutex BOOL ReleaseMutex (
HANDLE hMutex );
Пример i 1 . Использование мьютекса для организации к к тической секции. Пусть Процесс 1 создает два процесса: Проц . и Процесс 3. Процессы 2 и 3 содержат критические секции. В этом случае Процесс 1 содержит код: HANDLE hMutex = CreateMutex(0, false, "MyMutexName"); if(lhMutex) {.. Обработка ошибки} else{ CreateProcess (...); //Создание Процесса 2 CreateProcess (...); //Создание Процесса 3 WaitForMultipleObjects (...); //Ждем завершения проикгя // Освобождение объектов ядра CloseHandle (hMutex); CloseHandle (hProcess2); CloseHandle (hProcess3); return (0);
} Процессы 2 и 3 содержат код: HANDLE hMutex = CreateMutex(0, false, "MyMutexName '); if (!hMutex) {.. Обработка ошибки}
1
Здесь рассмотрена только структура программы с критической сепсиса ма программа.
182
WaitForSingleObject (hMutex, INFINITE); Начало критической секции Конец критической секции eleaseMutex (hMutex);
B
-seHandie (hMutex); метим, что функция CreateMutex в с о з д а н н ы х п р о ц е с с а х не рует новый мьютекс, а о т к р ы в а е т с у щ е с т в у ю щ и й , к о т о р ы й тяется по имени и н а х о д и т с я в о б л а с т и п а м я т и я д р а О С . пия WaitForSingleObject и с п о л ь з у е т с я д л я п р о в е р к и з а н я т о ыотекса. Функция ReleaseMutex и с п о л ь з у е т с я д л я о с в о б о ж ямьютекся после в ы п о л н е н и я к р и т и ч е с к о й с е к ц и и . Пример 2. Используя м ь ю т е к с ы , з а п р е т и т ь п о в т о р н ы й з а данного приложения. I ude <wmdows.h> Птп() char str[256J; mw(str, GetCommandLine ()); char *p - str; //Находим имя приложения (без учета каталога) char *pBeg = str, *pEnd ; while (1) {
pEnd = strchr (pBeg, 'U'J; if(lpEnd) break; pBcg = pEnd + 1 1 HANDLE hMutex = CreateMutex (0, true, pBeg); it (WaitForSingleObject (hMutex, 1)== WAIT TIMEOUT) I MessageBox (0, "Program runs...", "", MB OK); return 1;
} //Что-нибудь
выполняем
for (int i = 0; i < 100; i++);
MessageBox (0, "Press any key", "Information", MB_OK); ReleaseMutex (hMutex); CloseHandle (hMutex); return 0;
183
П р и запуске приложения создается мьютекс, имя которигсовпадает с именем п р и л о ж е н и я ( ф у н к ц и я CreateMutex). Е г я приложение запущено, данный мьютекс занят этим приложен!ем, поэтому код этого п р и л о ж е н и я может выполняться дал _ для других приложений с этим же именем мьютекс будет зал*!. Ф у н к ц и я WaitForSingleObject проверяет занятость мьютекса. В качестве временного интервала задан интервал 1 мс. Если мьютгк занят, т.е. экземпляр приложения у ж е запущен ранее, выход г 1 функции WaitForSingleObject произойдет через 1 мс. В этом с туче ф у н к ц и я WaitForSingleObject в о з в р а щ а е т WAIT TIMEOUT, и гг
грамма выдает сообщение «Program runs...». Если выполняет» поток, который занял мьютекс, выход из функции WaitForSh Object будет н о р м а л ь н ы м и в ы п о л н е н и е приложения пролм ж и т с я . Д л я проверки этой программы запустите один экзечтг приложения. Когда будет выдано сообщение «Press any key». » пустите второй экземпляр этого приложения. Тогда появится общение «Program runs...» и после н а ж а т и я кнопки ОК — в и из повторно запущенного п р и л о ж е н и я . 5 . 3 . 5 . Семафоры
Обычно используются д л я управления множествомрес /р * когда количество ресурсов более одного, хотя можно примеко д л я организации критических секций. Создание семафора. Ф у н к ц и я CreateSemaphore HANDLE CreateSemaphore( LPSECURITY_ATTRIBUTES LONG llnitialCount, LONG IMaximumCount, LPCTSTR IpName );
IpSemaphoreAttributes,
где: IpSemaphoreAttributes — атрибут безопасности для семафор (у нас равен 0); llnitialCount — начальное содержимое счетчика, опредгЖГ количество доступных ресурсов в начальный момент време: IMaximumCount — максимальное содержимое счетчика; IpName — и м я объекта. Используется для связи объектами разных процессов. Если текущее значение llnitialCount = 0, то нет ни одного р ступного ресурса, и все потоки, которые ждут ресурс (ФуюаИ| WaitFor...), будут заблокированы. 184
Br ли текущее значение llnitialCount > 0, то ф у н к ц и я Wait-
ыеньшает число доступных ресурсов на 1 и получает доступ ЗУ-
Р-иенение количества ресурсов. Функция ReleaseSemaphore.
:"0L ReleaseSemaphore (HANDLE hSemaphore, LONG IReleaseCount, mNGIpPreviousCount );
Функция изменяет количество свободных ресурсов на величиseCounf. Предыдущее значение счетчика доступных ресурывается в IpPreviousCount. Если значение этой переменной ейшем не используется, можно вместо нее задавать 0. Пример. Пусть одновременно можно запустить 4 потока, надо запустить 6 потоков. Используя семафоры, решить эту dude <windows. h> • dude <stdio.h> •WORD WINAPI fun (LPVOID); •IANDLE hFile; 'IANDLE hSem;
nfmainfj fiSem = CreateSemaphore (0, 4, 4,
0);// Свободных и всего 4 потока
iffhSem ==0){
printf f hSem = INVALID In"); return 1;
} HANDLE hThread[6]; DWORD i; DWORD Threadld(6]; rtp[J = {0, 1, 2, 3, 4, 5}; //Пытаемсясоздагпь 6 потоков kr(i=0:i<6;i++)f hThread[i] = CreateThread (0, 0, fun, p + /', 0, &Threadld[i]); if (hThread[i] == 0){ printf ("hThread[%d] = INVALID_HANDLE_VALUE\n", i); return 1;
-MultipleObjects (6, hThread, true, INFINITE); CloseHandle (hSern); for(i = 0;i<6; i++) CloseHandle (hThread[i]);
185
return 0;
} DWORD WINAPI fun (LPVOID p){ //Если можно, то выполняем потоковую функцию WaitForSingleObject (hSem, INFINITE); printf ("\nBegin p = %d\n", *(DWORD*)p); DWORD i; for (i = 0; i < 10; i++) putchar (*(DWORD*)p + 'a'); //Задержка for (i =0; i < 100000000; i++); printf ("\nEnd p = %d\n", *(DWORD*)p); // Освобождение ресурса ReleaseSemaphore (hSem, 1, 0); return *(DWORD*)p;
} П у с т ь п р и в е д е н н а я п р о г р а м м а в ы д а е т результат: Begin р = 0 ; начало работы потока О аааааааааа Begin р = 1 ; начало работы потока 1 bbbbbbbbbb Begin р = 2 ; начало работы потока 2 с с с с с с с с с с
Begin р = 3 dddddddddd End р = 1 Begin р = 4 ееееееееее End р = 3 Begin р = 5 ffffffffff End р = 2 End р = 0 End р = 5 End р = 4
; начало работы потока 3 ; конец работы потока 1 ; начало работы потока 4 ; конец работы потока 3 ; начало работы потока 5 ; конец работы потока 2 ; конец работы потока О ; конец работы потока 5 ; конец работы потока 4
О б р а т и т е в н и м а н и е , ч т о п о р я д о к н а ч а л а и конца пет* и о п р е д е л я е т с я т о л ь к о ОС, а н е п о р я д к о м в ы з о в о в соответствуй^^ функций в программе. Ж д у щ и е таймеры
И с п о л ь з у ю т с я в т о м с л у ч а е , е с л и необходимо использаЛ фактор времени. 1 о с
I"чание ждущего таймера. Функция CreateWaitableTimer ••ШЕ CreateWaitableTimer( INSECURITYATTRIBUTES IpTimerAttributes,
BOOL bManualReset,
LPCTSTR IpTimerName
pTimAtlributes — атрибут безопасности объекта. У нас равен 0; 84anualReset — ручной/автоматический сброс; .pTimerName — имя объекта. Используется д л я связи с объема из других процессов. Функция возвращает 0 в случае ошибки. |i и используется ручной сброс, то после освобождения ир\ютсявсе потоки, которые ждали этот таймер; если ис-д^.-ся автоматический сброс, то один процесс разблокируетР Ь т процесс выбирает ОС. При создании таймера для него устанавливается состояние 4М4№«.
Н тройка параметров ждущего таймера. Функция SetWaitКГимг. i-OL SelWaitableTimer ( HANDLE hTimer, ml
LARGE JNTEGER
*pDueTime,
LONG Period,
FTIMERAPCROUTINE pfnCornpletionRoutine,
LPVOID IpArgToCompletionRoutine, BOOL \Resume
Timer • дескриптор таймера; pDueTime — определяет начальный момент времени, когда нова станет свободным (начнет сигналить). Если pDueч* 0. то модуль pDueTime задает количество интервалов до вання таймера (в 100 наносекундных интервалах); %КХ) - определяет интервал времени в миллисекундах, чеорый каждый раз таймер становится свободным. Если этот Мрил равен 0, то таймер сработает только один раз; ACompletionRoutine — функция, которая будет вызываться я -'1батывании таймера (заголовок и параметры этой функции реныниже); IpArgToCompletionRoutine — адрес одного из параметров, кор передается функции, заданной предыдущим параметром; 187
fResume — определяет, будить ли систему, если срабатым ние таймера происходит во время, когда она спит. Если FResum' = true, то ожидающие его потоки получат процессорное время npi срабатывании таймера независимо от его состояния (бодрсшв или спит), если false, то ж д у щ и е потоки получат процессорное время только после пробуждения системы. Заметим, что ф у н к ц и я SetWaitableTimer не только настрм вает параметры, но по сути я в л я е т с я функцией ожидания, n"'J таймер не сработает в соответствии с заданными параметра*!. Поэтому после этой функции не имеет смысла ставить функаи WaitFor...
.
Рассмотрим заголовок и параметры функции, которая пвится в очередь системой д л я в ы п о л н е н и я при срабатыватн таймера (параметр pfnCompletionRoutine). Так как эту функции вызывает ОС, а не приложение, она называется функцией ofpc ного вызова. VOID (APIENTRY *РTIMERAPCROUTINE)( LPVOID IpArgToCompletionRoutine, DWORD dwTimerLowValue, DWORD dwTimerHighValue
); где: IpArgToCompletionRoutine — параметр, который передает:! этой функции в функции SetWaitableTimer; dwTimerLowValue,
dwTimerHighValue
—
м л а д ш и е и старпи*
32 бита д л я момента времени, когда произошло срабатывая! таймера. Д а н н а я ф у н к ц и я ставится в очередь потоку при сравнивании таймера. Время выполнения этой функции должно бит м е н ь ш е интервала времени м е ж д у последовательными cpri» т ы в а н и я м и . Эта ф у н к ц и я ставится в очередь потоку, котэ| А вызвал функцию SetWaitableTimer, но только в том случае, есз этот поток находится в ж д у щ е м состоянии, т.е. был заблоиц» в а н ф у н к ц и я м и (SleepEx, WaitForSingleObject и др.). Если пет*
не в ждущем состоянии, то ф у н к ц и я не ставится в очередь этвя потоку, поэтому очередь не переполняется. Таким образом, уИ> тока есть возможность отслеживать срабатывания таймера пА ко в том случае, если он «этого хочет» и ждет его срабатывал» Ф у н к ц и я о ж и д а н и я завершает свою работу только после o6p*fe ки всех элементов очереди, поэтому время выполнения фунхгобратного вызова должно быть меньше интервала времен 188
«тельными с р а б а т ы в а н и я м и . В п р о т и в н о м с л у ч а е ф у н к «идания не будет з а в е р ш е н а н и к о г д а . Пример. Составить п р о г р а м м у , в к о т о р о й т а й м е р н а ч и н а е т п гьчерез 2 секунды и п о д а е т з в у к о в о й с и г н а л к а ж д у ю с е к у н !1>чеиие 100 секунд. v Jwte <windows.h> Hude <stdic.h> ц agma hdrstop I 'СMe вдта argsused WliAPIENTRY TimerFun (PVOID par, DWORD ITmer, DWORD hTimer) UessageBeep (OxFFFFFFFF);
.I'namf)
HANDLE hTimer = CreateWaitableTimer(0, false, 0); ЦЯтег—0) pwilf ('Error CreateWaitableTimerW); return 1; LARGEJNTEGER HTirne; //Таймер сработает через 2 секунды UTime.QuadPart = -20000000; // 2 секунды BOOL b = SetWaitableTimerfhTimer, &HTirne, WOO.TimerFun, 0, false);
{
printf ("SetWaitableTimer - Error\n"); return 1; I for (int i = 0: i<100; i++) SleepEx (INFINITE, true); pnntf( Press any key..."); getchar (); return 0:
^ т и г е внимание, что в д а н н о м с л у ч а е д л я о ж и д а н и я н е . ,лтся функции Waitable... д л я о ж и д а н и я с р а б а т ы в а н и я
189
5 . 4 . Ф у н к ц и и о ж и д а н и я и объекты синхронизации Рассмотренные выше объекты синхронизации устанавли*! ют и используют свободное состояние, которое учитывается ф} • циями о ж и д а н и я . Н и ж е приведена сводная таблица для различных объем синхронизации, в которой заданы условия освобождения соотве ствующих объектов. Таблица i
Определение свободного состояния для различных объектов ядра Тип объекта Thread Process File Event Semaphore Mutex WaitableTimer
Когда устанавливается состояние «Свободы • Поток завершен (оператор return в потоковой функции или дошли до ее конца) Завершен последний поток процесса Операция ввода-вывода завершена Поток выполнил функцию SetEvent Счетчик ресурсов содержит значение, больше I1 (еще есть, что выделять) Поток освободил мьютекс, т.е. выполнил функцию ReleaseMutex Выполнено условие, заданное в функции SetWaitable Timer
5 . 5 . Вопросы и з а д а ч и 1. 2. 3. 4. 5.
6. 7. 8.
В каком случае необходимо использовать Interlock функции Используется ли критическая секция для синхронизаци цессов? Почему? Является ли критическая секция объектом ядра? В каком случае задается имя объекта ядра, используе гр синхронизации? Выберите объект синхронизации и реализуйте программус» жеством «читателей» и «писателей», когда читать мигут о временно несколько потоков, а писать — только один потек г ;v ложения. Выберите объект синхронизации и реализуйте программ' встречей нескольких потоков в одной точке. Что изменится, • :i встреча должна быть организована для процессов? Проверьте, не выполняется ли повторный запуск прило> гы Для проверки мьютекс не использовать. Используя ждущий таймер, реализуйте программу, kc ju подает звуковой сигнал в начале и в конце каждого час! Щ • с учетом вашего расписания. 190
6. УПРАВЛЕНИЕ П А М Я Т Ь Ю Цели изучения раздела: '. Объяснить понятие виртуальной памяти и ее р е а л и з а ц и ю на а п п а ратном и программном уровнях. Описать аспекты виртуальной памяти, т а к и е к а к к э ш и р о в а н и е , страничную и сегментную адресацию. 3 Объяснить компромиссные решения в терминах р а з м е р а памяти (основной, кэша) и скорости процессора i Описоть различные методы выделения памяти задачам, достоинства и недостатки каждого. Описать причину и способ использования кэш-памяти. 6 Сравнить страничную и сегментную о р г а н и з а ц и ю памяти. 1 Обсудить понятие пробуксовки, причины ее возникновения, методы обнаружения и борьбы с ней.
Память — дефицитный ресурс наряду со временем прокра. Так как задачи оптимизации приложений по памяти и If ни обычно взаимно противоположные, необходимо выбрать «пшальное соотношение между требуемым временем и памяМ> Основная память разделяется между компонентами ОС и 1 I -ами пользователя. В большинстве случаев общий объем ijrii-мой памяти превосходит объем оперативной памяти. По•»*у необходимо логически расширять объем памяти и отобраI-готическую память па физическую. Б..0К управления памятью должен выполнять следующие *е вные функции: эффективное распределение памяти в услоI : дефицита, обеспечение независимости адресного проЬюства для отдельных процессов, обеспечение возможности 191
использования процессами общей п а м я т и , не принадлежаще! ЯДРУ, управление памятью д л я каждого отдельного приложеннг В данном разделе рассматриваются общие принципы и ал.чритмы управления памятью.
6 . 1 . Виртуальная память ОС различают физическую (реально существующую) оп*р* тивную память и логическую. ОС расширяет логическую паняг процесса за пределы физической памяти. Процесс расширенна логической п а м я т и за ф и з и ч е с к у ю называют виртуальной ip г а н и з а ц и е й п а м я т и , а саму п а м я т ь — виртуальной памяти Так говорят, что виртуальное адресное пространство правки для 32-битных процессоров 2 3 2 , или 4 Гбайт, независимо от фи тнческого размера физической п а м я т и . Механизмы виртуальг-il памяти — одна из в а ж н е й ш и х составляющих современной оп*р» ционной системы. Что они из себя представляют? Управление памятью включает в себя следующие основа функции: — отображение логического адреса в физический; — распределение логической памяти между отдельными п?> цессами; — защита процессов друг от друга; — расширение логического адресного пространства за пре> лы физического. В общем случае механизмы виртуальной памяти позвоад» эмулировать обращение к определенной ячейке памяти. Эзг~л ц и я может осуществляться р а з н ы м и способами. Наиболее чмр используется способ, при к о т о р о м выполняется отображеви этой «виртуальной» я ч е й к и п а м я т и на какую-либо физичтп существующую ячейку памяти. Необходимость в использомв виртуальной памяти проявляется в многозадачной операциои^ системе наиболее полно. Рассмотрим этот случай подробнее. Будем называть код и данные процесса после загрузки irj» г р а м м ы в п а м я т ь образом процесса. Невозможно скопнровл образ процесса в произвольное место памяти и запустить его. лема заключается во внутренних ссылках, которые присутствуй в коде (это могут быть ссылки на данные, ссылки на какие-дА функции в коде и пр.). Если в объектном коде все адреса задав в в и д е Адрес начала секции + смещение, то в образе процесса щ 192
"х секций. Компоновщик определяет адреса начала секций л и команд) и формирует код с учетом этих адресов. После черациикод можно запускать, если адреса всех его секций с принятыми при компоновке. Очевидно, что в однозаiiсистеме проблемы с выполнением этого требования нет — тьку в каждый момент времени в памяти компьютера может ться только одна программа, можно выделить определеннее физической памяти и компоновать все программы по "адресу. А если система многозадачная? Одновременно в памяти на"•я несколько программ, которые д о л ж н ы находиться по
f
вать разные физические адреса. Рассмотрим способы виртуальной памяти. 6.1.1. Сегментная а д рреализации есация Ьначально виртуальная память появилась в виде сегментНргшзации памяти. Каждый адрес на аппаратном уровне заjuich двумя компонентами: адрес начала сегмента и смещение г ш этого сегмента. При изменении адреса загрузки изменяетeu^сегментов. Начальные адреса сегментов хранились в спе• .ьных регистрах, содержимое которых устанавливалось при .ке программы. При переключении процессов достаточно * I нагрузить в эти регистры новые значения, и к а ж д ы й процесс 1 I вялгя в своем собственном адресном пространстве. Процес<В«(?ащались к памяти по одним и тем же адресам, но теперь эти j отсчитывались от базовых адресов (базовый адрес — адрес •аа сегмента) сегментов, которые были разными у разных проI ч В результате эти обращения отображались на различные " Физической памяти. Основным недостатком сегментной адресации является то, "менты имеют разные размеры. При выгрузке/загрузке сег•н-в память фрагментируется, т.е. свободные и занятые участ-мятичередуются. Возникают ситуации, когда общий размер драг, памяти позволяет загрузить очередной сегмент, но нет Юпюго участка памяти требуемого размера — в этом случае • : вт не загружается. Кроме того, загрузка/выгрузка целиком 193
всего сегмента требует много времени. Поэтому болышшПЩВ временных процессоров не поддерживает сегментацию (од-1 е| исключений — процессоры архитектуры IA-32, которые сегментацию еще со времен 8086). 6.1.2- С т р а н и ч н а я а д р е с а ц и я
Суть страничной адресации в том, что все адресное простриство, предоставляемое процессором (на 32-битпых процесс < и ато, как правило, 4 гигабайта — 2 3z ), разбивается ни отреая , • ной длины (называемые страницами). Таблица страниц уп ливаат соответствие между виртуальным и реальным елркш страницы. Номер строки таблицы определяет виртуальный НЯ а содержимое строки — соответствующий физический адрр 1 статочно поменять содержимое заданной строки, п вкртуимМ адресу будет соответствовать другой физический адрес Ыжеш страницы являются единицей выделения — освобождена* Ш ти. Этот механизм также применяется для использование • данных и программ разными процессами. Так, в случаев! вания DLL они хранятся в памяти в одном экземпляре, в1 и ных процессах им соответствуют разные логические адреса i тные таблицы страниц). Особенности использования страшишИ адресации в современных процессорах рассмотрены ниже 6.1.3. К о п и р о в а н и е т о л ь к о п р и з а п и с и
Пусть пользователь запустил 2 раза одно и тоже придам» в условиях страничной адресации. В этом случае код в пахст будет записан только один раз. А данные? В мредвдушп «; сиях реализации многозадачного режима память для дш: J выделялась отдельно для каждого приложения. В соответ с режимом копирования при записи | метод COW сору с* для данных также выделяется одна и та же память. Выл •<• память отмечается как память «Тольно для чтения». При и попытке записи в такую страницу процессор сгенерирует н i • чение. Обработчик этого исключения сделает фпзическуг- *ои» требуемой страницы и снимет атрибут «Только чтение* с з М » ствующих виртуальных страниц обоих процессов. В ре -пг будут созданы копии только тех страниц, которые дейст) m . в этом нуждаются, что обеспечивает не только экономию шиш но и экономию времени для копирования данных в нриэчкаг страницах! 1S4
6,2, Аппаратные средства у п р а в л е н и я памятью Здесь будут рассмотрены средства управления памятью на •ре процессоров типа 1-32. При этом будет уделено внимание адресации данных, возможности использования вирту• и памяти, вопросам защиты адресного пространства отдель»- «ритожений. 6.2.1 .Адресация памяти
Адресация памяти в реальном режиме
Известно, что процессор после включения п и т а н и я нахо' я в так называемом реальном режиме. Д л я задания адреса шьном режиме используется 2 компонента: сегмент и смещек,-аждый компонент размером 16 бит. Сегмент задается в так аемом сегментном регистре, смещение — в регистре общего ;ения или константой. Размер компонента определялся, низ разрядности регистров процессоров 8086. Д л я обеспече« эвместимости с этими процессорами для реального режима ;гных процессоров используются компоненты такой же длидрес вычисляется по формуле: сегмент *16 + смещение.
(6.1)
Так как максимальные значения 16-битных компонентов OxFFFF, то максимальный адрес памяти, определенной по ?(1), равен 10FFEF, т.е. немногим более 1 Мбайт. Из этого ото пространства для программ операционной системы I»льзователя используется адреса 0 . . 0 x 9 F F F F , т . е . всего Ввит. Адресное пространство 0 x A 0 0 0 0 . . 0 x B F F F F исполья для хранения содержимого экрана монитора в текстовом iграфическом режимах, адреса OxCOOOO-.OxFFFFF содержат . : щи и данные, которые операционная система м о ж е т ис.швать для начальной загрузки (BIOS —• Basic I n p u t / O u t p u t ). В этой области памяти хранятся функции для работы ными устройствами: клавиатура, таймер, диски и др. в ре'"м режиме. В пользовательской программе могут быть установлены люэначения компонентов адреса. Никакие аппаратные средст• ыциты памяти одной программы от другой не предусмотреы Можно, конечно, программно обеспечить такую защиту, но De пространство в реальном режиме столь незначительно VoaiiT), что хранение в памяти модуля для з а щ и т ы адресного 195
пространства будет накладным. Вот почему запита памяти pt альном режиме не используется. Таким образом, сегментная адресация позволяет васп-гч программу и данные на адрес загрузки, но не позволяет зил тить их! Сегментная а д р е с а ц и я п а м я т и в з а щ и щ е н н о м режиме
Д л я использования всех возможностей процессора сои» менные приложения и ОС, как правило, функционируют • щищенном режиме. Таким образом, одной из первых фу) ОС должна быть функция переключения из реального ре в защищенный. Для обеспечения совместимости для задания адреса по- > j нему используются два компонента, как для реального p s d l | Адрес, заданный двумя компонентами, называется лошигаа адресом. Вместо 16-битного сегмента применяется 16 G«TI селектор, который по-прежнему задается в сегментной регату Вместо 16-бнтного смещения используется 32-битное смешеш которое задается в регистре общего назначения влп консгипй. В памяти всегда должны храниться: модули операционной ci— мы и модули одной или нескольких программ, каждый цЩ состоит из одного или нескольких сегментов (команд. дин-1 | стека). Для задания сегментов модулей, постоянно хранят 1 в памяти (модулей операционной системы), используете! Ifl называемая таблица глобальных дескрипторов (CDT М|| Descriptor Table). Для задания адресов модулей пользоватчя» программ используется таблица локальных дескрипторов(/1^ Local Descriptor Table). Обычно в памяти хранятся одна i»(R I несколько LDT по одной для каждого приложения. КвждМ • менту программного модуля соответствует одна строка т*л-г» дескрипторов. Выбор сегментного регистра определяется типом сггмгш По умолчанию для сегмента данных используется сегменте^ | регистр DS, для сегмента кода — регистр CS, для стека — S S . Кроме перечисленных выше сегментных регистров, использозать любой другой (£S, GS, FS). Например, адрес шм . IES.EAX+4] использует сегментный регистр ES. Для обеспечения обслуживания программных иоду1>« том привилегий для каждого сегмента процессор цоддержжсн 4 уровня привилегий (0..3): 0 соответствует наиболее при легированным сегментам, 3 наименее привилегирован^ J 106
Правило, уровень привилегии 0 назначается модулям ядра дионной системы, уровень привилегии 3 — пользовательпрограммам, остальные уровни привилегий могут использояшшитами операционной системы, драйверами. Г»лектор (сегментный регистр) включает в себя следующую мацию: -тип используемой таблицы (локальная или глобальная) — -уровеньпривилегии сегмента — 2 бита; - номер строки в соответствующей таблице дескрипторов — Так как для задания номера строки в таблице используется лов, максимальное количество строк в таблице равно 2 1 3 , ®192 строки. Таким образом, одновременно в памяти могут Нться 8192 сегмента, соответствующих GDT, и столько же ггов, соответствующих LDT. Строка таблицы дескрипторов имеет одинаковую структуру •ттаблиц. Рассмотрим назначение основных полей. Предел сегмента — определяется к а к размер сегмента — 1, ксимальное смещение в сегменте. Д л я 32-битного процесI я цел позволяет задать максимальный размер сегмента рав| 2 , или 4 Гбайт. Таким образом, предел определяет максие значение смещения в команде или для метки. Заметим, ™едел сегмента для стека задается не так, к а к для остальных итов. Допустимыми являются смещения от Предел + 1 до мально допустимого FFFFFFFF. Таким образом, размер стехсимальный, если значение предела для него равно 0. Начальный адрес сегмента (для стека — это адрес вершины .еслистек пуст). Для 32-битного процессора этот адрес зая 32-битным числом. Свойства сегмента. Некоторые из этих свойств я в л я ю т с я поиыми для данного сегмента, т.е. не изменяются в процессе мнения соответствующего программного м о д у л я . Другие I изменяются. К постоянным свойствам сегмента отногя такие свойства, как класс сегмента и его уровень привиле. Kiacc сегмента задает, что это сегмент команд, данных или Для сегментов данных и стека в поле типа задаются т а к ж е rnvrbie операции (чтение-запись). Д л я сегмента к о м а н д •типа можно установить флаг «Согласованный сегмент» иже). Кроме этих сегментов, которые называются обычны I пользуются специальные сегменты (системные), например, 197
шлюз, TSS и др. Назначение системных сегментов будет рас к трено ниже. Уровень привилегии сегмента определяется точно так жt, как уровень привилегии в селекторе. К переменным полях one сятся флаги: «Наличие доступа к сегменту» и «Наличие cein№ в памяти». Первый флаг устанавливается процессором ирв с личин доступа к сегменту, который задается данной строкой *• скриптора. Модуль управления памятью операциоаясй сясот использует этот флаг для определения сегмента, который дожив быть вытеснен из памяти в случае ее нехватки. Вытесняется * мент, к которому не было обращения наиболее долго. Прея* ш читать далее, подумайте, каким образом можно определить •• мент, не используемый наиболее долго, с помощью талого фх П Мы этот алгоритм даем в сноске, чтобы вы могли сначала сЦрмять ответ, а потом посмотреть одно из возможных реш- ' Другой модуль операционной системы, работающий в фс« • т режиме, должен сбрасывать этот флаг. Флаг наличия сет»"»» памяти устанавливается после загрузки сегмента в (шнетьиобю сывается после его вытеснения. Таким образом, на аппаратном уровне поддерживается чШ та от использозания «чужих» адресов памяти, защита от в сегмент, не предназначенный для этого (сегмент кодов Г* только для чтении). Адрес памяти, вычисленный по значениям его коми™»7 называется линейным, или виртуальным адресом. Рас >4|Я алгоритм вычисления линейного адреса памяти в защищена < режиме на примере команды. MOV [ЕВХ + ESI '4 * 165). ЕАХ без учета уровней привилегий сегментов данных и команд. В этом примера необходимо вычислить адрес памяти [ЕЙК • + ESI *4+ 165] для данных. Перед выполнением команд программы информации о г бальной и локальной дескрипторных таблицах заппсшсда i в регистры GDTR и LDTR, соответственно. В регистре GDTB ходится информация об адресе начала GDT и ее размере LDTP' держит смещение в GDT дескриптора, который соответствуй' 1 В дескрипторе находится информация об адресе и размере!У 1 При просмотре таблицы дескрипторов строки с установленным фигов ящШ записываются в конец таблицы. Когда необходимо определить пргт*ж**е«№ тесдание на памяти, выбирается первая строка данной таблицы.
198
Рассмотрим порядок вычисления адреса. 1- Так как по умолчанию с данными ассоциируется сегментi регистр DS, по этому регистру определяется таблица (млад
Если содержимое сегментного регистра не изменяется, шаг 1 •валяется только один раз. Линейный адрес используется в качестве исполнительного 1, если режим страничной адресации отключен. л1к следует из приведенного алгоритма, доступу к памяти твует группа проверок, которая защищает от использоI «чужих» областей памяти и от выполнения запрещенных дий. Так как адрес начала сегмента задается в дескриптор1т»М1це, а в команде задается только смещение относительно адреса, то перемещение сегмента в п а м я т и легко м о ж е т i выполнено без изменения самих команд за счет изменения s 1 вачала сегмента. Такой способ использования сегментной ции является наиболее надежным, но требует для каждого кния составлять заново LDT и модифицировать GDT, что ibbhhoусложняет управление программами. Рассмотренный метод адресации в з а щ и щ е н н о м р е ж и м е • ч недостатком сегментной адресации, связанным с разами размерами сегментов и фрагментацией п а м я т и , к а к вне (этот недостаток рассмотрен выше). ив проверка выполняется, так как адрес п а м я т и я в л я е т с я адресом ре-
199
Особенности использования FLAT-модели
Позволяет максимально скрыть сегментную структуру памяти от разработчиков операционной системы и пользовательски* программ. Используется два варианта FLAT-модели: основная (Basi 1 и защищенная (Protected). В случае основной модели создаются строки дескриптора и таблицы для всех сегментов, к а ж д ы й сегмент отображается на ' адресное пространство, т.е. для них задается адрес начала равным О и предел сегмента равным 4 Гбайт. Исключение по выходу v границы памяти не вырабатывается даже в том случае, ести за данный адрес превышает максимально возможный для физич ской памяти. З а щ и щ е н н а я модель отличается от базисной тем, что пре:°1 сегмента устанавливается равным размеру физической пам Д л я обеспечения з а щ и т ы кода операционной системы от ю i п о л ь з о в а т е л ь с к и х п р о г р а м м и с п о л ь з у ю т с я отдельные строк* в таблице дескрипторов для сегментов 0 и 3 уровней привилегк* И хотя все сегменты имеют по-прежнему одинаковые начальные адреса и пределы, обеспечивается з а щ и т а за счет применения правил работы в случае р а з л и ч н ы х уровней привилегий, кото^ис рассмотрены ниже. Проведите такой эксперимент. Выделите память во внешг области (сегменте данных) размером 100 байт, а заполните 110 Найдет ли эту ошибку компилятор, компоновщик, загрузчик Будет ли она обнаружена при исполнении программы? Объяснит? полученный результат с учетом особенностей FLAT-модели. Д л я этого примера можно использовать код: #include <stdio.h> char х[100]; int main(){ int i; for(i = 0;i< 110; i++) x[i] = 'a'; for (i = 0; i < 110; i++) printf C%c" x[i]); return 0;
} С учетом результата, полученного для предыдущего приме ра, попытайтесь определить результат выполнения следуюа I программы: 200
(Include <stdio.h> at main (){ n ti inta = 3.b = 5, с = 7; printf ("a = %db = %d с = %d\n", a, b, c); intx[100}; for(i = 0:i< 110; i++) x[i} = 1; printf ("\na = %d b = %d с = %d\n", a, b c); return 0;
F/лй результаты выполнения программ не совпадают с ожиLn in, просмотрите ассемблерный код, который был сгенери•Ш компилятором. Заметим, что результаты зависят от кон| • югокомпилятора. Таким образом, при программировании в 32-битном режиме |гтьзованием FLAT-модели нет защиты от выхода за пределы «г«'Нта. Проблема проверки выхода за границы индексов остаШм..'уадьиой, несмотря на использование защищенного режиащита модулей ОС осуществляется за счет использования ffc.'iBbix уровней привилегий для пользовательских приложеiri и модулей ОС. Заметим, что есть примитивное, но громоздкое ^mue проблемы проверки выхода за границы индексов. Д л я примера достаточно использовать следующий код: include <stdio.h> Met DEBUG «define CHECKBOUND(v) \ I fPMKprintff'Xs %d %s CHECKBOUND:Error\n'\ FILE__, L/WE #v) I ™turn 1;}} f.!se Шпе CHECKBOUND(v) •wdif lmain(){ int I inta = 3,b-5,c=7; printf fa = %d b = %d с = %d\n", a, b, c); intx[100]; for (i^O i < 110; i++){ CHECKBOUND (i < sizeof (x)/sizeof (int)); x[i]=1
}
printf ("\na = %d b = %d с = %d\na, b, c); return 0; 201
• В этой программе используется макрос CHECKBOUND проверки выхода за границы индексов. Выражение v имеет « чение «Истина», если индекс не выходит за границы, н «Ло»' • если выходит. Данный макрос автоматически включается. Ml задан режим отладки, и выключается в случае выключевв» ЩЯ режима (режим отладки задается константой DEBUG вереде i sual Studio). В случае, если выражение ложно (обнаружен «низа границы индексов), выводится имя исходного файлв (ковтота FILE ). номер строки в этом файле, где проверяете* mv (константа LINE ), само выражение, при проверке кого;- - * ниружена ошибка, и строки CHECKBOUND.Error. Д а т ы ! игрможно использовать для проверки индексов для много»» род массивов. Например, для двухмерного массива, содержагг строк и 80 столбцов, выражение д л я проверки имеет влл: i>=0 && I <25 && ]>=0 && j < 80. 6 . 2 . 2 . Страничная организация памяти для 1-32 Вся память делится на страницы фиксированного ради» Оперативная память выделяется и освобождается по одной —>»• нице, благодаря атому исключается фрагментация. Классически для организации страничной испол •,» >« одноуровневая, двух- и трехуровневая адресация. Одноуровневая адресация при страничной о р г а н и з а ц и и памяти
Вся память делится на страницы. Составляется Tit • • страниц, в которой записываются физические адресе пот at вательных логических страниц. В атом случае элемент т«1 должен иметь длину, достаточную для записи одного вдресг L» 1 32 битных процессоров это 32 бита. Количество строк ti( | определяется, исходя иг возможного размера внртуалъноВ вм» ти и размера страницы. Например, при размере внртуальв d « мяти 4 Гбайт и размере страницы 4 Кбайт (это р е а л ь н ы е | для рассматриваемых типов процессора) количество строк цы должно быть равно 2 З Й /2 1 *, или 2 2 0 . С учетом длины и» элемента (4 байта) размер таблицы равен 4 Мбайт. Беля root что сама эта таблица должна быть в памяти н для каждой &и » должна быть своя таблица, то такой метод приводят к бсишш затратам памяти для вспомогательных таблиц. Поэтому - J способ применяется для современных процессоров тольь»
страниц размером 4 Мбайт и используется только ОС. ния пользователя не работают в таком режиме. Д|ухуровневая страничная адресация
"ля каждой задачи (приложения) и с п о л ь з у ю т с я к а т а л о г Directory — PD) и таблица страниц (Page Table — РТ). В каопределяются адреса таблиц страниц. К а ж д а я таблица содержит адреса страниц. .Адреспамяти, вычисленный по алгоритму (см. 6.2.1), поступи блок трансляции адреса (БТА). Алгоритм работы БТА. !. Адрес делится на 3 компонента размером 12, 10 и 10 бит, 1енно, начиная с младшего. Обозначим их, соответственAMU2. L АО определяет значение смещения внутри страницы. Так ад смещение отводится 12 бит, то размер страницы соответ;к до равен 212, или 4 Кбайт. 3.AJ определяет номер строки в таблице страниц РТ. Так к а к к з -ер строки отводится 10 бит, то максимальное количество •Л» равно 210, или 1024. Так как к а ж д а я строка д о л ж н а содер> -. дрес начала страницы, то ее размер 4 байта и размер РТ I»*? 4 Кбайт, или одна страница. Одна таблица может задавать Ujrwe пространство размером 1024 с т р а н и ц ы и л и 4 Мбайт. Ъы образом, можно определить количество таблиц страниц ости от адресного пространства, которое требуется д л я ния. Например, если приложению необходимо 32 Мбайт, ф> I то должно быть определено 8 таблиц страниц. 4. А2определяет номер строки в каталоге PD. Так к а к под нот к и отводится 10 бит, то максимальное количество строк или 1024. Так как каждая строка должна содержать . начала РТ, то ее размер 4 байта и размер PD равен 4 Кбайт, | • шой странице. В памяти обязательно должен быть каталог, • . шло только один. Адрес его начала находится в управляаам регистре CR3. Дметим, что если поля АО п А1 объединить в одно поле и Ирц*. ить этим полем значение смещения внутри с т р а н и ц ы , * <ы переходим на одноуровневую о р г а н и з а ц и ю с т р а н и ч н о й Цвдии с размером страницы 2 22 , или 4 Мбайт. Напоминаем, «" > настоящее время такими страницами можно пользоваться «нил'иа 0 уровне привилегии, т.е. модулям ядра ОС. 203
Трехуровневая страничная организация
В отличие от двухуровневой структуры, адрес Диви» • на 3. а ни 4 компонента — АО, А1, А2, A3, начиная с иыдаи битов. Размеры компонентов 12, 9, 9, 2 — соответствен» « АО, А1, А2 используются как для двухуровневой организашп. • максимальное количество строк таблиц уже не 1024, я 5' - Т» как размер таблицы остается 4 Кбайт, размер строки таЬ »< увеличивается в 2 раза, что позволяет для адреса неполной® 64 бита. Из этих 64 бит фактически для задания адреса i эуется 24 бита вместо 20 для всех предыдущих страниц. Эк ч ляет расширить адресное пространство до 2 ав По.те/3 спредеи шредая* таблицу каталогов и задает адреса 14 каталогов. В случи- Ч |уч*г Пй уровневой страничной адресации можно использовать § ь Баша* страницы размером 2 Мбайт, если поля АО и А1 объедини в одно поле. Почему виртуальная и страничная адресация являются с и н о н и м а м и ?
Вы, наверное, уже поняли, почему, но мы все-таки р« рнм еще один пример. Пусть имеем 64 Мбяйт свободногощц* » го пространства в оперативной пямяти. Пугть очередяое при жение требует для исполнения 12R Мбайт памяти. В яте» MW будет составлено 128/4 32 таблицы страниц (одна табло» aft деляет адресное пространство размером 4 Мбайт). По мере вел «» зования этих страниц им будет выделена реальная память, • • значены адреса оперативной памяти. Если для очередной данных оперативной памяти не хватает, страницы, к(г<«« в использовались наиболее долго, будут вытеснены из памятя _j требуемых данных будет предоставлена память. При вогчяр использовании данных, вытесненных из памяти, им св<« .'j* предоставлена память, но адрес памяти в обоих случаях хааг не совпадать. Тогда не придется изменять команды прогри» нужно будет только изменить соответствующую табяшуспрвв Таким образом, адрес, заданный в команде, фактически виртуальным адресом, по которому вычистяется реаэьны!^^^™ предоставления памяти данной странице. Очевидно, виртуальной пямяти зависит только от разрядности пр (сейчас используются 32-битные и 64-битные процессоры).
2:
Наличие или отсутствие страницы в пямяти отсяе» процессор с помощью механизма прерываний (гл. пожг)
11
Тмнм образом, память для кодов и данных выделяется поачно. Адрес начала страницы кратен ее длине, т.е. 4096 I страниц в пользовательском режиме. Если область данных 'ся с адреса 4095 и занимает 2 байта, потребуется выде> х ?вгрузить 2 страницы, или 8092 байта, а не 2. Вот почему отке критических приложений необходимо знать разшцы и выравнивать данные соответствующим образом! I выравнивания необходимо контролировать и в случае ювания меток внутри циклов, чтобы не получалось, что таетствует адресу в конце таблицы и часть команды нача одной странице, а другая часть — на другой. Дополнительная информация о страницах
Lk известно, адрес начала страницы, в том числе и таблицы ц, и каталога всегда кратен размеру страницы. Это значит, ние 12 бит адреса всегда нулевые. Эти биты в таблицах ютгя для задания дополнительной информации. Допол1 информация позволяет определить: страницу для записи и/или чтения; - присутствие с т р а н и ц ы в п а м я т и ;
- уровень привилегии страницы (0 — системная, 3 — польская); - быдп ли изменения в данной странице (используется для ftiiLta необходимости записи содержимого страницы на диск •fwe ее сброса). Устанавливается процессором при доступе Певице в режиме записи. Сбрасывается программой анализа; - £ыл ли доступ к странице (используется а л г о р и т м а м и Щ^ кЕПя претендента на вытеснение из памяти 1 ); зежимы использования кэша (см. ниже). Ели используются большие таблицы, то в строке каталога егся, что данная строка соответствует не таблице страI (большой странице. Ти.пм образом, на аппаратном уровне процессор позволяет использовать страницы трех размеров, отслеживать их твие в памяти, задавать для них р е ж и м ы доступа и уроь илегии. Если страницы в памяти нет (бит присутствия . в памяти сброшен), процессор генерирует исключение, в ; ; в"рожных алгоритмов реализуется фоновой программой, которая I ю» | а переписывает те страницы, к которым осуществлялся доступ. 11. не претендент на вытеснение находится на вершине этого списка. 205
которое обрабатывает ОС. ОС устанавливает значение этих гов и сбрасывает их при обработке исключения и формирован!! таблиц. Обработчик исключения должен выполнить следующр действия: — найти свободную страницу или освободить занятую, ест нет свободных; — загрузить страницу в память; — загрузить адрес страницы в РТ. Если необходимо, еде п изменения в PD; — обновить страницы в к э ш е страниц; — возвратиться к команде обращения к памяти, которая звала данное исключение З а д а н и е страничной адресации
По умолчанию после в к л ю ч е н и я компьютера страничви адресация выключена. Включает страничную адресацию ОС включения страничной адресации необходимо: — создать каталог и таблицы страниц, соответствующн кущему сегменту кода естественной адресации. Под естествен^» будем понимать адресацию, при которой линейный и физически адреса совпадают. Напоминаем, что адреса всех таблиц долж быть кратны размеру страницы; — если используются большие страницы, установить ф и страниц большого размера (флаг PSE, бит 4 регистра CR4) MOV ЕАХ, 1 SHL 4 OR CR4, ЕАХ;
— если используется 36-битный адрес, то установить бит ширенной адресации (флаг РАЕ, бит 5 регистра CR4) MOV ЕАХ, 1 SHL 5 OR CR4, ЕАХ,
— записать адрес начала каталога в регистр CR3 MOV ЕАХ, offset DirTable MOV CR3, ЕАХ;
— включить режим страничной адресации (бит 31 регистра С" MOV ЕАХ, 1 SHL 31 OR CRO, ЕАХ
1 Здесь опущен шаг, с в я з а н н ы й с проверкой к э ш а . Вопросы, относящиес11 • шу, будут рассмотрены н и ж е .
Стратегия подкачки и выгрузки страниц
При использовании страничной памяти ОС необходимо ре.1ть проблемы: -определить, какие страницы д о л ж н ы быть удалены из -определить, какие страницы д о л ж н ы быть з а г р у ж е н ы I Шить: определить методы загрузки-выгрузки страниц. Страницы удаляются из памяти, если не хватает п а м я т и для у-ииц, которые должны там быть. Страницы, занимаемые ядром ОС, не выгружаются. При решении вопроса о выгрузке страниц используются сле| Tie алгоритмы: •оптимальный алгоритм. При необходимости выгрузки вы1»(1"ся страница, к которой не было ни одного обращения. НеI' Ш к — необходимо знать всю историю работы со страницами; •алгоритм с преданализом. Анализируются страницы, коЦнс будут затребованы в очередных командах активных про- "В. Страницы, которые должны использоваться далее, не мгругаются. Недостаток метода: требуется а н а л и з процессов v ки зрения требуемых страниц — это очень дорого с точки г , я ресурсов; •случайныйвыбор. Выгружаемая страница выбирается слуг равномерным распределением. Достоинство: не требует ифирнации о ранее и позже используемых страницах; •хронологический порядок. Страницы выгружаются в по(С)'их загрузки. Достоинство: просто организовать очередь. Звлаток: может быть выгружена страница, которая необходи«> наследующем шаге выполнения; • хронологический порядок с учетом использования (LRU — Recently Used — использованный раньше всех). Выгружап.- страница, которая не использовалась наиболее долго. Д л я -*"iemw таких страниц формируется не очередь, к а к в предыjtW* варианте, а список используемых страниц. Страница, коvU используется, записывается в конец списка. Выгружаются зршцы, находящиеся на вершине списка. Очевидно, что на •тшгае списка при таком алгоритме всегда находятся страниV °е используемые наиболее долго. Недостаток: может быть ш-Т. «ена страница, которая необходима на следующем шаге •в -чения. 207
К а к показали экспериментальные исследования [6], по оптимального алгоритма, который на практике не применяет наиболее эффективным является метод LRU. Этот метод наибо"часто используется современными ОС. Учет этого алгоритма п зволяет уменьшить число смен страниц. Для уменьшения числа смен рекомендуется обрабатывать данные до конца, т.е. сна :т» выполнить все требуемые операции с одними данными, потом с другими, так к а к при работе с одними и теми же данными сменстраниц не требуется. Р а б о ч е е множество
Рабочим множеством называют множество страниц, кото| используется программой [10]. Д л я определения рабочего mi жества можно применять данные о размерах кода и данных и исполняемого файла, соответствующего процессу. Рабочее « жество служит для оценки разных стратегий управления стран*;, и эффективности планирования использования ресурсов. Определение рабочего набора и его свойства. Пусть в моменты времени 0, 1, 2, ... используются странн: с номерами: Р2, РЗ, P I , Р6, Р З , Р4, Р2, Р6, Р 6 , Р5, РЗ, Р6, РЗ. В соответствии с алгоритмом нахождения наиболее давно i пользуемых страниц получаем: Р1, Р4, Р2, Р5, Р 6 , Р З . В рабочий набор в к л ю ч а е т с я половина страниц, котор! использовались недавно, для нашего примера — это Р5, Р6, Р Предполагается, что рабочий набор содержит наиболее ссыл» мые страницы д л я программы. Программа может быть выполнена в том и только в томг чае, если страницы ее рабочего набора находятся в памяти ница из рабочего набора не может быть удалена из памяти, есл выполняется соответствующая программа. Л о к а л ь н ы й и глобальный методы управления страницами
Локальный метод предполагает, что для каждого npoi выделяются страницы в соответствии с их рабочим множество Алгоритм управления страницами применяется для каждой пр граммы в пределах ее рабочего множества. Глобальный метод предполагает, что ОС владеет всем га жеством страниц, которые выделяются по мере надобности н2 0 8
»t«o от приложения, для которого они выделяются, т.е. д л я • приложений используется ц е н т р а л и з о в а н н ы й м е х а н и з м it шения. В этом случае для страницы необходимо хранить инмацию о принадлежности этой страницы приложению. Тогда . мая область программы — величина переменная, так к а к для j «итого же адреса виртуальной памяти могут быть выделены и- еые области физической памяти, а значит, разные страницы. Пробуксовка
Пробуксовка — ситуация, которая возникает при большой мту-ше системы в связи с большим числом процессов и нехвати физической памяти. В этом случае происходит очень частый ••И данными между диском и физической памятью, что приво№ к 'ущественному уменьшению производительности. Такую •тх щию можно промоделировать следующим образом. Пусть все рим все процессы используют страницы с разными номерами, р емчисло используемых страниц на 1 больше размера физиче1 памяти. После использования страниц с номерами 0, 1, ... п I :п используются эти же страницы. Так к а к число используе10 границ на 1 больше, чем максимум для физической памяти, f ар j выделении памяти под страницу п необходимо выгрузить Вмяти. Пусть для выгрузки используется алгоритм выгруз|(~>)ницы, которая не использовалась наиболее долго. В этом lf\Kбудет выгружена страница с номером 0. Но именно д а н н а я - «вида должна использоваться на следующем шаге, поэтому у;.-г выгружена страница 1 и загружена страница 0. Очевидно, •в' он случае для каждой новой страницы будет выполняться ишя замены страниц — режим пробуксовки. Способы борьбы с пробуксовкой: увеличение размера физической памяти; - ограничение числа активных процессов; - уменьшение требуемого объема памяти д л я процессов; -специальные алгоритмы выделения страниц (анализ стране пгорые должны использоваться далее). Алгоритм управления страницами
Страницы могут быть в одном из 3 состояний: Свободна — страница может быть выделена любому процессу. Занята — страница выделена одному из процессов, но пока ^гческая память, соответствующая данной странице, не выкл'Ш.
209
Закреплена — страница выделена одному из процессе», зическая намять, соответствующая данной странице, выделен Менеджер страниц (системный процесс) при загрузке я* ложения (создании процесса) выделяет ему страницы в соопи ствии с рабочим набором (делает эти страницы завятьшн). По просу приложения выполняется закрепление требуемых nj» ниц за физической памятью. Одновременно ведется список кг пользуемых страниц или включаются счетчики, отсчитывиопр интервал времени после последнего обращения к стравиц? & 1 для очередного выделения страниц свободных страниц в«, Щ освобождаются страницы, не используемые наиболее долг- Eta применяется счетчик для отсчета интервала времсии, то ' »• ти выгружаются страницы, не используемые в течение з ш п О интервала временя. При ныгрузке страниц возможна кг *• диск (перемещение) или просто сброс, если стравнпа не лась после последнего прикрепления к физической памяти. При завершении процесса Менеджер страниц ocBo6a».jrft память, выделенную для процесса ая счет перенесения все* | ветствующих ему страниц иэ списка занятых в список CBO&.WG страниц. Ток как сегмент задачи (TSS) содержит указательва .. i * страниц (регистр CR3), каждому процессу соответствуют cwt и талог и таблицы страниц. 6.2.3. Особенности виртуальных адресов для 6 4 - б и т н ы х п р о ц е с с о р о в
Линейный виртуальный адрес задается 64 битами. PijM 3 бита используются для задания регионов, всего ножа, -о* 8 регионов, для задания адреса каждого региона нсполцуг* 61 бит. Если 64-битный процессор используется 32-6итао411 то старшие 32 разряда адреса нулевые. Каждому регнг — ветствует специальный регистр, который содержит 24-р»зр*лн1 J идентификатор региона. Идентификатор можно рассллтув как старшие цифры виртуального адреса региона, в этом » всего для задания адреса отводится 61 + 24, или 85 разряди Щ • регионы имеют идентификаторы, обрезующие последователи* J значения, можно получить единое адресное пространство, puq | которого 2 85 байт. Обычно ОС создает 62-битное адресное простг* ство для виртуального адресного пространства процесса, пи» же адресное пространство для ввода-вывода данных и 6 З-fi гост 210
•;>!свое пространство для разделяемых данных. Каждому pernio можно задать свои размеры страниц по умолчанию. Виргуишй адрес состоит из 3-х компонент: номер региона (Virtual him Number) — старшие 3 бита, номер страницы (Virtual Page Richer) и смещение в странице. В регистре для каждого региона psiiTCH размер страницы, который и определяет число бит, отвшых для смещения в странице. Под число битов отводится Ват, минимальный размер страницы равен 2 1 2 байт, он соотЩгтгует нулевому значению этого поля. Максимальный размер рринцыравен 212 6 байт, что соответствует 256 Кбайт. Определим размер таблицы страниц. Р а з м е р региона раи 261, количество страниц размером 4 Кбайт равно 2 6 1 / 2 1 2 = бант Один элемент таблицы страниц равен 8 байт, т.е. одно Винное слово, поэтому общий размер таблицы страниц равен If сайт. 6.2.4. Кэширование
I В современных компьютерах быстродействие оперативной .Ш»г:и во много раз уступает быстродействию процессоров. Д л я •Кования этих модулей, работающих на разных скоростях, Ьаьзуется промежуточная память (кзш-память). В данном •ИИерссматривается принцип организации, управления и ис«вания кэша с точки зрения системного программиста. к
Принципы организации кэш-памяти ( К П )
Кэш-память (КП) — память с быстрым доступом (по скорости руна сравнима с регистрами). Кэш используют для хранения 'фгшх и команд. Для увеличения скорости вычисления адреса Включенной страничной адресации КП используется д л я храбрея элементов текущих страниц. Различают внутреннюю и внешнюю КП. Внутренняя КП рас•вжена на одной пчате с самим процессором. I Объем внутренней памяти зависит от типа процессора. Н и ж е I (В. К.2.4) будут рассмотрены программные средства определе«я параметров кэш-памяти. Используется 2- и 4-блочная кэш. Ьшс.лтво блоков (банков) определяет, сколько байтов физичеВ( памяти с общими свойствами может быть загружено в кэше j (еанига). Размер блока определяет, сколько байтов загружается Шныри обращении к данному (переменной) или команде. •I Структура внутренней и внешней кэш-памяти одинакова.
1
211
Д л я определенности предположим, что используется 4-н> правленный кэш, размер блока равен 16 байтов, а размер к"~та равен 8 Кбайт. Структура такого кэша представлена на рис. 6 1 Блок данных КП состоит из двухмерного массива, каждал строка которого содержит 4 элемента по 16 байт. Таким образом в одной строке кэш-памяти может быть записано 64 банта Ко личество строк КП определяется к а к отношение общего разы* ра кэша к размеру одной строки. Например, для КП емкость" 8 Кбайт имеем: 8 * 2 1 0 / 6 4 = 2 7 ( 1 2 8 строк).
>я я о 5гН С
16 бнйт
16 байт
21 бит
21 бит
21 бит
21 бит
со
Блок данных
Блок тэгов
16 байт
Блок LRU и достоверности
Рис. 6.1. Структура КП Д л я каждой строки к э ш а задается дополнительная ивфст"" д и я (блок тэгов, блок достоверности и LRU). Д л я задания связи содержимого кэш-памяти и ячейки пак г ти, для которой это содержимое задано, используется полет*> * которое определяет старшие биты адреса памяти для соответгь ющих блоков. Таким образом, адрес j блока в i-ой строке вы: к И ется по формуле: (Тэгюш«(й+1));.(1«1), где: i, j, k, I — номера строки и столбца в кэше, соответстве k, I — число битов, отводимых д л я номера строки и pa <-г блока, соответственно; Tar[i][j] — старшие р а з р я д ы адреса в j колонке i-ой стро» 212
Алгоритм определения адреса в кэш-памяти. Физический 32-битный адрес делится на 3 компонента: -смещение внутри одного элемента к э ш а (для 16-байтного H'jера элемента кэша задается I = 4); - номер строки массива (число битов определяется числом • н в кэше, для нашего примера задается 1 = 7) — определяет, Ш ой строкой кэша работать; - поле тэгов — оставшиеся старшие биты (для нашего причте 32 — (к + 1) определяют старшие 21 бит адреса, который ЧЧеляетКП. Таким образом, размеры компонентов определяются физичеи размерами кэша. Для однозначного определения адреса, соответствующего Ьмевту кэша, все значения тэгов одной строки д о л ж н ы быть Нршыми, т.е. нельзя записать в одну строку тэги для адресов, вторых совпадают старшие 21 бит. Поле достоверности 4 бита (по одному для каждого элемента 1 и). Поле достоверности устанавливается в 1, если соответ(I '"ций элемент КП заполнен данными, и О, если еще пустой. Блок LRU (Least Recently Used) — 3 бита — будет рассмотрен Пример. Рассмотрим запись в КП блока п а м я т и с програмв. Пусть программа начинается с адреса 00001OOOli и занимает Нпамяти Пусть КП пустая. Заметим, что начальный адрес iu ,шиси в кэш должен быть кратен 16. Поэтому адрес начала (at • ванных, как правило, кратен 16. Физический адрес OOOOlOOOh с о д е р ж и т :
-младшие 4 бита задают смещение внутри 16 байт (равны 0); -очередные 7 бит равны 0, т.е. используется нулевая строка пои - старшие 21 бит содержат 0...010 = 2, именно это значение •Кется в свободное поле тэгов 0 строки, у нас свободны все т>'и, заполнение начинается с нулевого столбца; этот столбец г,|те достоверности отмечается к а к з а н я т ы й (достоверный), ie 16 байт программы запишутся в нулевую строку, нулевой Ели команды программы выполняются последовательно, t iJiie выполнения команд, занимаемых первыми 16 байтаi, в иш загружается очередной блок сегмента кодов с адресом Ш010Н: 213
м л а д ш и е 4 бита р а в н ы 0, т.е. смещение очередного Ь" равно 0; средние 7 битов р а в н ы 01, следовательно, очередной блл из 16 байтов будет з а г р у ж е н в нулевой столбец, 1 строку. Т " к образом, программа займет 2 0 h строк нулевого столбца кэш-и м я т и . П р и многократном в ы п о л н е н и и любого участка кода щи повторном выполнении этот код у ж е будет в кэше, и повторг записи кода не требуется. Если количество 16-байтных блоков программы больше 12" и л и 80Н, заполняется 1 столбец к э ш а и т.д. при размере кодовое сегмента не более 4 Кбайт. Е с л и размер кода больше 4 Кбайт, требуется из 4 з а н я т ы х блоков требуемой строки выбрать тот, к р ы й не использовался наиболее долго. Не всегда выгрузка из к э ш а требуется при полном н и и К П . П о к а ж е м это. Номер строки кэша, куда отобража-п адрес п а м я т и , определяется значением среднего поля (в наш * примере это 7 битов с номерами 4 . . 10). Одни и те же строки к.ш отводятся д л я адресов п а м я т и , с в я з а н н ы х между собой соотнош нием: Адр н о в = Адр ста р + k * Р а з м е р столбца кэша, где k — любое целое число. В этой формуле Адр нов — адрес - л ного, д л я которого определяется номер строки кэша, АдРспр адрес данного, д л я которого номер строки уже определен. Ее в программе последовательно используются элементы мессии, адреса которых удовлетворяют в ы р а ж е н и ю (6.2), то эти элементы отображаются на одну и ту же строку К П , т.е. фактическиисп"" зуется одна строка к э ш а вместо всей К П , и выгрузка данног »s к э ш а требуется д а ж е в т о м случае, если все остальные строки К свободны. Д л я определения элемента к э ш а , который должен бьггьвь; гружен, применяется стратегия LRU [см. 6.2.2]. Д л я этого используется 3 бита LRU. Алгоритм ф о р м и р о в а н и я битов LRU. 1. Если обращение к полю 0 и л и полю 1, то LRU[0] уставлю вается в 1, если к полю 2 и л и 3, то LRU[0] = 0. 2. Если обращение к полю 0, то LRU[1] устанавливается в I и н а ч е в LRU[1] = 0.
3- Если обращение к полю 2, то LRU[2] устанавливается в 1 и н а ч е в LRU[2] = 0. 214
Так как поле LRU занимает 3 бита, в нем могут быть записаIiv шачения000...111. Алгоритм определения поля для выгрузки. 1. Если LRU[0J==1, то поля 0 и 1 не выгружаем, иначе поля 2 ».'че выгружаем. I.Если LRU[0] ==1 && LRU[2] ==1, то в ы г р у ж а е м поле 3, . «-иоле2. I. Если LRU[0] -=0 && LRU[1] =-1, то в ы г р у ж а е м поле 1, | че-поле2. Пример 1. Определим поле, которое не использовалось наиMl долго, если в LRU записано ООО. Так KIIKLRU[0] = 0, то поля 2 и 3 не выгружаем. Так как LRU[1] = 0, то выгружаем поле 0. Пример 2. Определить выгружаемое поле, если биты LRU ..-дат 101. tnKKBK LRUfOJ = 1, то поля 0 и 1 не выгружаем. Гак как LRU[2] = 1, то выгружаем поле 3. Проанализируйте «справедливость» такого алгоритма. Не *иг ли один элемент пары «запрятаться» за другим элементом, использовался последним? Приведенный выше алгоритм я в л я е т с я ч а с т н ы м случаем •етдотма бинарного поиска и используется в случае, если необ"тииоэффективно найти один из 2п элементов, например, фальI то монету и др. Говорят, что произошло попадание в кэш, если выполняется Хищение к области памяти, которая уже в кэше. После записи очередного значения в КП при его изменении ir-тически новое значение записывается в соответствующую 4»ть памяти. Такой режим называется режимом сквозной за№1. Это единственно возможный режим д л я внутренней К П . liii внешней КП можно использовать режим з а п р е т а сквозной :шкн. когда содержимое кэша не записывается в память до его о. Это позволяет ускорить работу, когда промежуточные ре.р-иы не записываются в память. Ятя управления режимами работы КП используется управй регистр CR0. Так как изменение этого регистра возможI; 1ько в привилегированном режиме, р е ж и м ы работы с КП тяются ядром ОС. Бит NW(not write throuh) (29) — запрет сквозной записи — яет режим записи для внешнего кэша; 215
Б и т CD (Cache Disable) — запрещение КП. Новые дани.' в КП не записываются. Но обращение к старым данным возможвс. и результаты записываются только в к э ш без обновления памяп Значения битов NW и CD д л я различных режимов при; д в таблице. CD Выполняемые действия NW 0
0
КП разрешена. Используется сквозная запись (режим по умолчанию)
0
1
Такая комбинация битов не используется
1
0
Кэш разрешена. Не используется режим обратной связи
1
1
Кэш запрещена и запрещена сквозная запись. Кэш исп I зуется как очень быстрое ЗУ. Может быть кратковречеь'ш включен
В случае использования страничной организации п .neti специальный блок КП используется в качестве буфера преоб[ вания адреса и хранит элементы таблицы страниц (TLB — t: • lation lookaside b u f f e r ) . Буфер заполняется и освобождается 11 мим процессором. В таблице каталогов и таблице страниц задаются биты упри ления КП для конкретного каталога и страницы. PCD (Page CD) — запрещение кэша; PWT (Page WT) — бит сквозной записи. П р о г р а м м н о е определение параметров КП. К о м а н д а CPUID
Из предыдущего пункта следует, что незнание пара» ':» I КП может привести к существенным потерям за счет испольэ мн и я не всей, а только части к э ш а процессора. Это особенно вам д л я системных программ. Д л я определения параметров КП необходимо: 1. Определить, что команда CPU ID поддерживается дан * типом процессора (бит 21 Cflags можно установить в 1): ft include <stdio.h> int main(){ int Bit21 = 1 « 21; boot Error = false, asm { pushfd pop eax Or eax, Bit21 Push eax 216
Popid Pushfd Pop Test Jnz mov OK:
eax eax, Bit21 OK [Error], 1
} printf ("%s\n", /Error? "OK": "Error"); return 0
Программа выводит сообщение OK, если команда поддержиR.
2.Определить максимальное значение регистра ЕАХ, коточожно задавать команде CPUID. -ov еах, О CPUID гот [dwMaxValue], еах "ста результат не менее 2, то параметры КП узнать можно. 3. Выполнить команду CPUID для еах = 2. Параметры кэша аются в регистрах ЕАХ, ЕВХ, ECX, EDX. AL показывает раз нужно выполнить команду CPUID с еах = 2 д л я полуполной информации. Самый старший бит регистра показысоцержит ли регистр информацию о кэше. Если информация жптся, то она задается побайтно. Полное описание команды дено в документации. Рассмотрим кодировку некоторых )в: 01
Буфер для т р а н с л я ц и и с т р а н и ц (Translation lookaside
buffer — TLB) для сегмента кодов, 4-направленная, 32 строки, общий размер кэша 4 Кбайт. 02 — TLB для сегмента кодов, 2 элемента, 4 мегабайтные страницы. 03 - TLB для сегмента данных, 4 направленная, 64 строки, общий размер кэша 4 Кбайт. "4 TLB для сегмента данных, 8 элементов, 4 мегабайтные страницы. № Кэш команд, 4-направленная, размер строки 32 байта, общий размер кэша 16 Кбайт. ОС — Кэш данных, 4-направленная, размер строки 32 байта, общий размер кэша 16 Кбайт. 13 - L2 Кэш, 512 Кбайт, 4-направленная, размер строки 32 байта. 217
6 . 2 . 5 . Выводы п о о б з о р у а п п а р а т н ы х средств у п р а в л е н и я памятью
Обзор методов управления памятью на аппаратном уровне показал, что аппаратные средства современных процессоров под держивают работу с виртуальной памятью на уровне сегуентноГ и страничной памяти. При использовании этих средств обеспечена возможность з а щ и т ы сегментов и страниц за счет задания : уровня привилегии. Имеются программные средства управления КП для ядра ОС. Н и ж е будут рассмотрены алгоритмы и средства управления памятью, применяемые современными ОС, а также функции да управления памятью на примере WinApi.
6 . 3 . Алгоритмы и средства управления памятью Большинство современных ОС используют страничную орг» низацию памяти. В дальнейшем предполагается, что испольгтт ся этот режим работы процессора. Модуль управления должен выполнять следующиеосновгиг функции: — выделение памяти д л я н у ж д ОС и пользовательских п,)« ложений; — освобождение памяти. 6 . 3 . 1 . В ы д е л е н и е п а м я т и . О б щ и е принципы
При выделении памяти необходимо учитывать следумш ограничения: — некоторые процессоры старых образцов могут раб ~ т> только с первыми 16 Мбайт п а м я т и . Если ОС должна поддер вать работу таких процессоров, то это ограничение должно чвтываться; — для современных ОС недостаточно виртуального пропг*» ства 2 3 2 байт, может потребоваться объем виртуального простри ства больше этой величины. Очевидно, что работа со старшим! адресами этого виртуального пространства должна быть обесг^* на особыми способами; — аппаратные средства работают не с виртуальной, а с фи « ческой памятью, поэтому выделение памяти для буферов вне них устройств должно выполняться т а к ж е особыми средствам 218
iB связи с вышеизложенными ограничениями вся память дек на 3 зоны: - зона памяти до 16 Мбайт — используется старыми устрой-зона памяти до (232 - 1) байт включительно, используется дыми модулями ОС и приложениями; -зонапамяти, начиная с 2 32 байт, используется, если ОС и южения поддерживает 36-битную или 64-битную адресацию. Для упрощения защиты адресного пространства ОС некото|0С делят виртуальное адресное пространство на 2 участка. ~ый соответствует адресному пространству п р и л о ж е н и й , й —адресному пространству ОС. Так, д л я WINDOWS 2000 яое пространство делится пополам, м л а д ш а я половина отвояриложениям пользователей, старшая — ОС. В этом случае проверки возможности использования адреса д л я программ "вателя достаточно проверить только старший бит виртуго адреса. В современных версиях ОС, которые используют •прием для распределения памяти между пользователями и «ерхнюю границу адресного пространства приложений можно -ть при настройке ОС. Для обеспечения возможности выделения памяти ядро ОС но знать информацию о к а ж д о й странице в и р т у а л ь н о г о аого пространства. Системные таблицы (PD, РТ, см. 6.1.2) жат некоторую информацию о страницах, но этой информаЬщостаточно (вспомните, какая информация хранится в этих идах!). Так, ядро должно быстро найти свободный участок ~ и в заданной зоне и заданного размера, поэтому ему необхоиметь информацию о свободных регионах памяти (регион — рывный участок памяти, в котором находятся страницы из ' зовы). Если требуемого региона нет, то ОС должна быстро , дить необходимую память. Для этого ОС должна хранить ж всех используемых страниц, в котором последние страниаются в конце списка. При загрузке ОС память выделяется для модулей ядра ОС Ьгёверов, которые загружаются на этапе загрузки. Строятся Пни свободных регионов в разных зонах, списки используемых •шц, которые могут выгружаться в процессе работы системы, дается резервная память, необходимая д л я восстановления Мкмы. ^Основная проблема стратегий выделения памяти — фрагменпамяти; если фрагментация сильная, бывает невозможно 219
выделить необходимый участок памяти, хотя общий размер а бодной памяти превосходит размер требуемой памяти. Есть три пути уменьшения фрагментации: — выделение из массива свободных блоков мишшилио» блока с учетом требуемого размера; — использование схемы формирования адреса, когда не прерывная последовательность страниц соответствует неи( ному линейному пространству: — использование специального алгоритма, основаквсго : двоичном поиске, обеспечивающего быстрый поиск н обыдшние смежных свободных блоков. Первый способ требует, чтобы список свободных реготь i был упорядочен в порядке увеличения размера региона В случае требуемый свободный регион находится в данном соки при просмотре сначала списка. Оставшийся элемент аалжсш ется в нужное место, начиная с начала списка. Тахны сйрака требуется 2 просмотра списка регионов: для поиска необходим региона и для записи остатка в список. Если список достаю*» большой, что часто бывает в реальной ситуации, то этот ; работает медленно. Кроме того, если размеры выделяемой ндш/л произвольные, то адреса начала выделен вой памяти будут произвольные, что приведет к неэффективному обращению к мяти. Поэтому операционные системы выделяют блоки пямяп с произвольного размера, а в единицах, кратных, по меньшей размеру элемента кэша. Второй способ основан на возможности преобразован!* непрерывного физического адресного пространства в яепрерю ное виртуальное пространство. Рассмотрим пример. Пусп бодными является О, 2 и 6 страницы физической памяти П) — необходимо выделить 3 страницы непрерывной области Построим таблицу страниц, в первую строку которой здыШ! адрес начала О страницы (00000000). во вторую строку — I начала второй страницы (00002000'), в третью строку - щх: начала 6 страницы (00006000). В этом случае дявным фра роеавным физическим страницам будет соответствовать ли ве!«« виртуальное пространство. Недостатки этого способа: тревуг—" корректировка таблиц страниц, а изменение таблицы правд к сбросу кэша страниц, что уменьшает скорость доступа к лам * г 1 Клппмивасм, что размер страницы 2й байт, задается трем* шестшишо МИ цифрами.
220
t( ie того, буфер для некоторых внешних устройств не может к ь выделен по этой технологии, там действительно требуется • тывное физическое адресное пространство. В зависимости от требуемого размера блока памяти, который Вю выделить, используются разные а л г о р и т м ы . Рассмотрим •*па алгоритм для выделения областей памяти, к р а т н ы м стра1 а потом выделение небольших блоков памяти. 6.3.2. Выделение больших блоков п а м я т и
Ятя больших блоков единица выделения памяти — страница. Наиболее часто используется алгоритм близнецов (buddy sy•• algorithm). Все свободные регионы распределяются между 10 списками Ilei-умости от их размера в страницах: 1, 2, 4, 8, 16, 32, 64, Я Ь и 512страниц непрерывно. Адрес начала каждого блока рги размеру блока, например, для региона длиной 1 страница вачала кратен 4096. Если размер региона 16 страниц, то *
кратен 211 * 2 12 = 2 2 8 . "ассмотрим работу а л г о р и т м а н а п р о с т о м п р и м е р е . Выделение памяти.
.'сть запрос на выделение 128 страниц, или 27 * 212 = 2 1 9 , о 12Кбайт. Алгоритм проверяет, существует ли свободный In iсписке с блоками в 128 страниц. Если такой блок есть, он •ттается из списка свободных блоков и его адрес возвращает II -честве результата работы алгоритма. Если такого блока нет, В а м шцет свободный блок в списке с большим размером — И страниц. Если такой элемент есть, то выбирается этот эле•v то младшая (с меньшим адресом начала) половина исполь№ я для удовлетворения запроса, а вторая половина заносится •вгок свободных размером 128 страниц. Если нет свободного и к», тс просматривается следующий больший блок и так далее Мищения непрерывного блока. Для оставшейся части нерасширенной памяти соответствующие элементы списка формиР я таким образом, чтобы адреса блоков были упорядочены, с дешли до самого большого размера блока (512 страниц) и •ладный блок не найден, то функция выделения памяти возвраошибку. В данном случае максимальное число просмотров Ы* шпу списков (10). Освобождение памяти. Освобождаемый блок записывается • 1У9.;:ый список. Место этого блока определяется по его адресу Йви;:лйем, что адрес начала блока кратен его размеру в байтах, |
п
221
т.е. адрес принадлежит списку I. если он содержит 12 + I ву в конце). Если в списке записаны два смежных элемента, on у* лязотся из втого списка и записываются в список с большим римером. Алгоритм выполняется рекурсивно до тех пор, яои» смежные блоки. При этом необходимым условием объединили является не только смежность блоков, но и кратность адрес» »< чала блока с меньшим адресом размеру большего блока. Для каждой зоны используются свои списки, т.е. фактж*ски 3 группы списков. Каждая группа списков использует следующие группы ж вых. Для ускорения поиска в списке смежных блоков параду' мим списком можно использовать битовые карты. Размер м—а определяется числом регионов в списке (равен пх половине1 IМ устанавлизается в О, если оба региона свободны или оба ишт, и I - в противном случае. Если в битовой кярте стоит 0 нсоот» ствующие регионы е списке, то они объединяются. 6.3.3. В ы д е л е н и е н е б о л ь ш и х б л о к о а памяти
Цель этого алгоритма, как и предыдущего — обеспечеа«инимальной фрагментации памяти. Всистеме многообъек * « дартного размера, которые необходимо создавать н ункчтожг", достаточно часто. ОС выделяет непрерывную область ак1«я» ваемых страниц с помощью алгоритма близнецов. Эту п а х т С использует для массивов своих стандартных объектов, размер которых 32, 64, 128 4096 (Slab Allocator), т.е. изменяли в геометрической прогрессии. Такие изменения размере» спечивает выравнивание выделенных блоков на грая иду. т е ьделенный адрес всегда делится на длину выделенного блом %Л каждого размера фактически используются два блоке DUUII. один для внутренних целей, другой — для приложений. Приер* ми таких объектов являются дескрипторы, в том числе десхрП тор файла, дескриптор процесса и других объектов ядра Kuffil объект этого типа имеет флаг занятости, который уставааятв и сбрасывает ОС. В атом случае внутренняя фрагментация асш чается. Запросы определенного размера, которые встречаю»-» часто, могут быть выполнены достаточно быстро за счет создай» множества специальных объектов, которые имеют onpexeaand размер. Для упрощения и ускорения работы с этими массам» могут быть сформированы списки свободных и занятых зла» тов массивов. 222
6.4. Обзор функций для у п р а в л е н и я памятью Гзвременные ОС имеют однотипные функции д л я управлеЭти функции позволяют управлять виртуальной, [ческой и выполнять отображение внешней памяти на опечую, что особенно широко используется при загрузке прилоЗдесь будут рассмотрены соответствующие ф у н к ц и и д л я 0WSAPI[3].
Пдоятью.
64,1. Архитектура памяти в W I N 3 2 Виртуальное адресное пространство
Каждому процессу ОС выделяет виртуальное адресное проВг.'во, размер которого определяется разрядностью процес132-битного процессора этот размер составляет 2 3 2 , или а, для 64-битного процессора — 2 6 4 , или 16 экзабайтов. инаем, что виртуальное адресное пространство определятатимый набор адресов, а не фактический размер ОП. Это ? пространство делится на разделы, которые зависят от ательными являются разделы: для кода и данных польльекого режима, для кода и данных р е ж и м а ядра. Оба эти 1 имеют практически одинаковый размер для 32-битного тора. Для 64-битного процессора объем первого раздела ательского) равен 2 42 , или 4 Тбайта. Второй раздел (для s ОС) может иметь любой требуемый объем. Раздел д л я кода 1ЕЫХ пользовательского режима содержит данные и код проа, является закрытым от других процессов. В разделах д л я I я данных режима ядра хранятся код ядра ОС, драйверы вйств. Все эти модули доступны всем процессам. Здесь вы!тся память под объекты ядра. Сюда загружаются все системе DLL. Для каждого процесса эти DLL находятся по одному и •г' же адресу. Если пользовательский поток попытается обратно одному из адресов этого раздела, то формируется ошибВицения к памяти. Регионы в адресном пространстве
Адресное пространство, выделенное процессу в момент соз|ия, практически все свободно (не зарезервировано), за исиением области памяти, на которую отображены код и данI квтветствующей программы. Для резервирования п а м я т и дуется функция VirtualAlloc. Эта ф у н к ц и я соответствует 223
функции выделения больших блоков памяти. Начало выделениоь области п а м я т и система выравнивает на границу, называемую гранулярностью п а м я т и (allocation granularity). Эта величине зависит от типа процессора. Д л я процессоров типа Intel и AI (32- и 64-разрядных) она составляет 64 Кбайт. Это означает, 411 адрес начала выделенной области всегда кратен этому размер}. Так к а к память фактически выделяется в страницах, то р • мер региона всегда кратен размеру страницы. Размер выделяв в области всегда округляется до полного числа страниц в больш с сторону. Чтобы использовать память, выделенную функцией Virtva Alloc, необходимо выделить физическую память (committing) и задать связь между виртуальной и физической памятью (спрос цировать вторую на первую). Размер физической памяти може быть меньше, чем виртуальной. Это имеет смысл делать, например, если записи используются последовательно. В этом случафизическая память может выделяться последовательно для од. или нескольких записей и освобождаться после использован,-я (decommitting). Физическая память, выделенная этой функций, обнуляется. Как и большинство современных ОС, WINDOWS исполни ется так называемый страничный файл (paging file), куда сбра;Ывается содержимое страниц п а м я т и , если необходимо ее освобо дить. Страничный файл задается на диске. Размер определяет! установками ОС. Размер физической памяти равен размеру от ративной памяти + размер страничного файла. Для получения информации о размере страничного файла для WINDOWS 2000 необходимо выбрать Control Panel/System/Advanced/Performanc Options. Здесь же можно изменить этот размер, если вы пме°тр права Администратора. Если данные, к которым обращается пользовательский питок, находятся в страничном файле, то эта страница помещается в оперативную память и выполняется обращение к этим данным В этом случае, возможно, потребуется переписать другую страницу из оперативной памяти в страничный файл. Здесь необходимо помнить о недопущении пробуксовки (см. 6.2.2). Заметим, что страничный файл не используется при затру ке приложения. При загрузке приложения с жесткого диска ОС определяет размер кода и данных д л я этого приложения (по и полнимому файлу), образ файла рассматривается как зарезерви224
ш регион, т.е. фактически код и данные не копируются ь, пока они не используются. Пслучае запуска приложения с дискеты, оно сначала копиI в ОП. Если нагрузка на память велика, то в страничном вделяется память под образ этого п р и л о ж е н и я д л я его кошяпри необходимости. Это связано с тем, что приложение инимать более одной дискеты. При многократном использовании одного п р и л о ж е н и я (DLL) жи используется один и тот же фрагмент памяти. ВнаШ нескольких экземпляров сегмента данных т а к ж е ис""ется общий фрагмент памяти. Этот фрагмент выделяется утомзащиты PAGE_WRITECOPY. Данный атрибут означаем в данную страницу выполняется запись, то потоку выаличная копия этой страницы. Это обеспечивает наиболее ~вяое использование памяти для р а з л и ч н ы х процессов. 6.4.2. Исследование виртуальной памяти Системная и н ф о р м а ц и я
Формируется функцией GetSystemlnfo: /010 GetSystemlnfo ( LPSYSTEMJNFO IpSystemlnfo ); IpSyslemlnfo — адрес н а ч а л а с т р у к т у р ы т и п а SYSTEM INFO
мной информацией. Структура SYSTEMJNFO: tpM struct _SYSTEMJNFO{//sinf union { DWORD dwOemld; struct { WORD wProcessorArchitecture; WORDwReserved; } }•
DWORD dwPageSize; LPVOID IpMinimumApplicationAddress; LPVOID IpMaximumApplicationAddress; DWORD dwActiveProcessorMask; DWORD dwNumberOfProcessors; DWORD dwProcessorType; DWORD dwAllocationGranularity; 22
5
WORD wProcessorLevel; WORD wProcessorRevision; }
SYSTEMJNFO;
dwOemld — остается д л я совместимости с предыдущими сиями WINDOWS. Начиная с WINDOWS NT 3.51 и WINDOW используется поле wProcessorArchitecture объединения (ut Система всегда устанавливает это поле в 0. wProcessorArchitecture — определяет архитектуру сист»>1 процессора. Может принимать значения: PROCESSOR_ARCHITECTURE_UNKNOWN PROCES SO R_ARCHITECTURE_ INTEL PROCESSOR_ARCHITECTURE_MiPS (WINDOWS NT 3 51) PROCESSOR_ARCHITECTURE_ALPHA (WINDOWS NT4.0) PROCESSOR_ARCHITECTURE_PPC (WINDOWS NT4.0) PROCESSOR_ARCHITECTURE_IA64, PROCESSOR_ARCHITE" URE_IA32_ON_WIN64, PROCESSOR_ARCHITECTURE_AMD64 64M WINDOWS)
wReserved — р е з е р в . dwPageSize — р а з м е р с т р а н и ц ы . IpMinimumApplicationAddress — у к а з а т е л ь на минимальны!
адрес, доступный приложению и DLL. IpMaximumApplicationAddress — у к а з а т е л ь на максима.:* ;
допустимый адрес, доступный приложению и DLL. dwActiveProcessorMask — определяет маску для рассм ваемого процессора системы. Б и т 0 соответствует процессор, I' бит 31 — процессору 31. dwNumberOfProcessors — количество процессоров в систем? dwProcessorType — и с п о л ь з у е т с я д л я совместимости со п*
рыми ОС. dwAllocationGranularity — определяет адрес выравнивания единицу измерения выделяемой виртуальной памяти (гран; it; ность). wProcessorLevel — д о п о л н и т е л ь н ы е сведения о процес ;•
с помощью которых можно определить возможность исполыов!ния улучшенных свойств, т а к и х к а к 36-битная адресация, и (См.
ф у н к ц и ю IsProcessorFeaturePresent д л я определения э
особенностей). wProcessorRevision — определяет архитектурно зависит I дополнительную информацию о процессоре. 226
Пример программы для формирования системной информаиконсольном режиме: i nclude <windows.h> hnclude <stdio.ti> include <stdlib.h> Include <string.h> ttpragma hdrstop inlmainf) SYSTEMJNFO si; GetSystemlnfof & si); printf('dwPageSize = %d\n", si.dwPageSize); printf("lpMinimumApp/icationAddress=%p \n" si.lpMinimumApplicationAddress); printf("lpMaximumApplicationAddress=%p\n", si.lpMaximumApplicationAddress), printf('dwAllocation Granularity= %d\n", si. dwA Ilocation Granularity ); printl ("dwNumberOfProcessors = %d\n", si.dwNumberOfProcessors); printf ("dwActiveProcessorMask - %x\n° si.dwActiveProcessorMask); WORD wProcessorArchitecture; printf ("wProcessorArchitecture = %d\n", si.wProcessorArchitecture); printf("wProcessorLevet = 80%c86\n", si.wProcessorLevel + '0'); printf ("wProcessorRevision = %c%d\n", (si.wProcessorRevision»8) + A', si.wProcessorRevision & OxFF); return 0;
} Пример результата работы программы:
f
dwPageSize = 4096 lpMinimumApplicationAddress=00010000 iximumApplicationAddress=7FFEFFFF i!wAllocationGraniilarity=65536 dwNumberOfProcessors = 1 dwActiveProcessorM ask = 1 «ProcessorArchitecture = 0 wProcessorLevel = 80686 wProcessorRevision = H3
Результаты означают, что при выделении виртуальной памяп минимальный блок имеет размер 65536 байт. Размер страницы 1 байт, диапазон адресного пространства д л я п р и л о ж е н и я ра»"п0010000.. 7FFEFFFF, используется процессор 686. 227
Статус виртуальной памяти
О п р е д е л я е т с я ф у н к ц и е й GlobalMemoryStatus, которая зад,
текущее состояние виртуальной и физической памяти. VOID GlobalMemoryStatus( LPMEMORYSTATUS IpBuffer );
где: IpBuffer — у к а з а т е л ь на с т р у к т у р у MEMORYSTATUS с инфор
мацией о памяти. Структура
MEMORYSTA TUS:
typedef struct _MEMORYSTATUS { / / mst DWORD dwLength; //размер MEMORYSTATUS DWORD dwMemoryLoad; //процент использования памяти DWORD dwTotalPhys; // байт физической памяти (всего) DWORD dwAvailPhys; // свободных байт физической памяти DWORD dwTotalPageFile; //всего байт страничного файла DWORD dwAvailPageFile; // свободных байт страничного файла DWORD dwTotalVirtual; // общий размер виртуального // пространства DWORD dwAvailVirtual; // свободных байт } MEMORYSTATUS, *LPMEMORYSTATUS;
Пример использования ф у н к ц и и : ttinclude <windows.h> #include <stdlo.h> ttinclude <stdlib.h> ttinclude <string.h> ttpragma hdrstop int main(int argc, char **argv) { MEMORYSTATUS ms; ms.dwLength = sizeof (ms); GlobalMemoryStatus (&ms); printf ("dwMemoryLoad = %d\n", ms.dwMemoryLoad); printf ("dwTotalPhys = %08x\n", ms.dwTotalPhys), printf ("dwAvailPhys = %08x\n", ms.dwAvailPhys); printf ("dwTotalPageFile- %08x\n", ms.dwTotalPageFile); printf ("dwAvailPageFile= %08x\n", ms.dwAvailPageFile) printf ("dwTotalVirtual= %08x\n", ms.dwTotalVirtuat); printf ("dwAvailVirtual= %08x\n", ms.dwAvailVirtual); return 0;
} 228
Результаты работы программы: j.iMemoryLoad = 77 dwTotalPhys = 0df89000 dwAvailPhys = 03327000 dwTotalPageFile= 18beb000 dwAvailPageFile= 0f40a000 Wolal Virtual = 7ffe0000 jwAvailVirtual= 7f9b8000
Результаты работы программы показывают, что память за•а 77% (первое значение), общий размер физической памяти рюоо, из них свободны 03327000 байт, общий размер странич|м памяти 18beb000, из них свободно 0f40a000, общий размер •рталъной памяти 7ffe0000, из них свободно 7f9b8000 байт. Заметим, что состояние памяти может изменяться в ходе Си нения процессов. Если размер оперативной п а м я т и и л и грпичного файла может быть больше 232, необходимо вместо кции GlobalMemoryStatus использовать ф у н к ц и ю GlobalMewyMsEx, в которой для задания всех размеров использовать U | "'вые числа. Определение состояния адресного пространства
Можно определить состояние заданного диапазона страниц < ирттальном адресном пространстве процесса. Функция VirtualQuery (VirtualQueryEx) DWORD VirtualQuery( LPCVOID IpAddress, fWEM0RV_BAS/C_ INFORMATION IpBuffer, DWORD dwLength ); U
IpAddress — указатель на адрес области страниц, которые |; """ируютгя. Это значение округляется с учетом границ стра1Ы.
LpBuffer — адрес буфера, куда записывается и н ф о р м а ц и я iNIEMORYBASICJNFORMATION).
DwLength - размер буфера (байт). Возвращаемое значение: действительное количество байт, пых в буфере. Замечание. Функция VirtualQuery возвращает информацию довательных страницах, начиная с заданного адреса с поtiO атрибутов: Состояние всех страниц (MEM_COMMIT, MEM RESERVE, M_FREE,
MEM_PR/VATE, 229
MEM_MAPPED
или
MEMJMAGE).
Если страницы не свободны, значит, они выделялись г"" цией VirtualAlloc. Атрибуты доступе ( P A G E _ R E A D O N L Y . PAGE_ READWPAGE_NOACCESS, PAGE_WRITECOPY. PAGEEXECUTE PA® EXECUTE READ. PAGE_ EXEC UTEREADWRITE, PAGE EXE, r TEWRITECOPY, PAGEJGUARD или PAGE_NOCACHE). Функция начинает определение с первой страницы сг.. хг на, а затем проверяет остальные страницы и возвращаетатр|>п» и размер в байтах области с атрибутами, совпадающим с . т г бутами первой страницы. К примеру, если свободны 40 bFw, я функция Virtue/Query вызвана для области, начиная с 10 МШ-. функция возвратит рвзмер свободной области 30 Мбайт Эта функция определяет информацию дли страниц теку»" процесса, я функция — для страниц зя до иного процесса. Структура PMEMORY_BASIC_INFORMATION: typedef struct MEMORY_BASICJNFORMATION{//mbl PVOID BaseAddress; PVOID AltocatiorBase. DWORD AHocetionProtect; DWORD RegionSize: DWORD State; DWORD Protect; DWORD Type; } MEMORY_BASlC_INFORMATION; typedel MEMORY BASIC .INFORMATION 'РЫБЫ BASIC_ INFORMATION:
-1'
где: BaseAddress — базовый адрес страничного диапазона fpuный IpAddress, но округленный до границы страниц в мен! л» сторону). AllocationBase — указатель на адрес региона, виде--»•-• функцией VirtualAlloc (начало, конец). Страница, заданная в Ба» Address, содержится внутри этого диапазона. AllocalionProtect — определяет атрибуты доступа при першначальном выделении памяти. Могут использоваться флаги: PAGE_READONLY — страница только для чтения. Бел система отличает такие файлы от файлов для исполним, при попытке исполнить и, в любом случае, при noi вапнеи — ошибка. PAGE READWR1 ТЕ — страница для чтения-записи. PAGE_WRITECOPY — при записи в страницу форнпруся ее копия (для страниц физической памяти). 230
PAGE_EXECUTE — для страниц в физической п а м я т и . Ошибка доступа при попытке чтения-записи. PAGE_EXECUTE_READ — режим чтения-исполнения для страниц в памяти. PAGE_EXECUTE_READWRITE — для исполнения, чтения и записи для страниц в памяти. PAGEEXECUTEWRITECOPY — для исполнения, чтения и записи страниц в памяти. Страницы разделяемы для чтения-записи и для копирования при записи. PAGE^GUARD — защищает с т р а н и ц у от доступа. Может комбинироваться с любыми флагами, кроме PAGE_
mccEss. PAGE_NOACCESS — полностью выключает доступ к страницам в памяти. PAGE_NOCACHE— позволяет не кэшировать страницы из памяти. Устанавливается при работе с аппаратурой (драйверы). Не рекомендуется использовать. RegionSize - суммарный размер (в байтах) страниц, начиная 'к "даоадреса. Весь регион имеет те же атрибуты з а щ и т ы , что рвая страница. Slate — состояние страниц региона: МЕМ_С0ММ1Т — память выделена или в физической памяти или в страничном файле. MEM_FREE — свободная страница, не с в я з а н н а я с процессом. MEM RESERVE — зарезервированная с т р а н и ц а , но не связанная. Protect - атрибуты защиты страниц региона. Могут быть замфлаги защиты. Задается флагом AllocationProtect. Туре — определяет тип страниц: MEMJMAGE — показывает, что страницы п а м я т и внутри области отражаются в секции изображения. MEM_MAPPED — показывает, что страницы памяти внутри области отражаются в секции просмотра. tJEM_PRIVATE — показывает, что страницы памяти внутри области приватны (не разделяются с другими процессами). Функция VirtualQueryEx используется для получения той же •фмации, но уже для любого процесса. Пример. Составить программу для анализа состояния памят» 1 |я области памяти, доступной для текущего процесса. 231
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> int mainQ { SYSTEMJNFO si; GetSystemlnfo( &si); LPVOID minP= si.lpMinimumApplicationAddress; LPVOID maxP= si.lpMaximumApplicationAddress; printf("IpMinimumApplicationAddress=%p\n", si.lpMinimumApplicationAddress); unsigned long begin - *(unsigned long *)minP; int j; static MEMORY_BASIC_INFORMATION mbi; LPVOID IpAddress = minP; DWORD dwLength = sizeof (MEMORYBASICJNFORMATION); while ((unsigned)lpAddress < (unsigned)maxP) { DWORD ten = VirtualQuery( IpAddress, &mbi, dwLength ); if (ten > dwLength) printf ("Error length\n"); printf ("BaseAddress=%p\n", mbi.BaseAddress); printf ("AllocationBase = %p\n", mbi.AllocationBase); DWORD dw=mbi. Allocation Protect; printf ("AllocationProtect=%s\n", (dw&PAGE_READONLY)==PAGE_READONiy? "PAGEREADONLY": (dw&PAGE_READWRITE)==PAGE_READWRITE? "PAGE_READWRITE": (dw&PAGE_WRITECOPY)=-PAGE_WRITECOPY> "PAGE_WRITECOPY": (dw&PAGE_EXECUTE)==PAGE_EXECUTE? "PAGE_EXECUTE": (dw&PAGE_GUARD)==PAGE_GUARD? "PAGEGUARD"; (dw&PAGE_NOACCESS)==PAGE_NOACCESS? "PAGE_NOACCESS": "PAGEOTHER "); printf("RegionSize=%d\n", mbi. RegionSize); printf("State = %s\n" (mbi.State & МЕМ_СОММ1Т)==МЕМ_СОШГ' 232
"MEM_COMMIT": (mbi. State & MEM_ FREE)=FREE ? "MEM_FREE": "MEM_ RESERVE"); printf("Type =
%s\n'\
(mbi.Type&MEM_ IMA GE)==MEM_ IMA GE? "MEMJMAGE": (mbi. Type&MEM _ MAPPED)==MEM_ MAPPED ? "MEM_ MA PPED": "MEM_PRI VA ТЕ"); IpAddress = (BYTE*)lpAddress + mbi.RegionSize; return 0;
Программа может выдать результат (приведена информация •мо о некоторых блоках): mumApplicationAddress=00010000 BaseAddress=00010000 AtationBase = 00010000 AflocationProtect=PAG E_RE A DWRITE RegionSize=4096 State=MEM_COMMIT ~ype = MEM_PRIVATE BaseAddress=00011000 /JocationBase = 00000000 h ocationProtect= PAG E_OTH E R RegionSize=61440 "'ate=MEM_FREE rype = MEM_PRIVATE BaseAddress=00020000 A ocationBase = 00020000 AllocationProtect=PAGE_READWRITE RegionSize=4096 State :MEM_COMMIT Type = MEM_PRIVATE BaseAddress=00030000 VIocationBase = 00030000 |bcaflonProtect=PAGE_READWRITE RegionSize=1036288 State = MEM_RESERVE Type = MEM_PRIVATE 233
BaseAddress=00130000 AllocationBase = 00130000 AllocationProtect=PAGE_READWRITE RegionSize=16384 State = MEM_COMMIT Type = MEM_PRIVATE BaseAddress=00231000 AllocationBase = 00230000 Allocation Protect=PAGE_READWRITE RegionSize=61440 State = MEM_RESERVE Type = M E M M A P P E D
BaseAddress=00400000 AllocationBase = 00400000 AllocationProtect=PAGE_OTHER RegionSize=4096 State = M E M C O M M I T Type = M E M J M A G E BaseAddress=7FFE1000 AllocationBase = 7FFE0000 AllocationProtect=PAGE_READONLY RegionSize=61440 State = MEM_RESERVE Type = MEM_PRIVATE
И н ф о р м а ц и я о свободном регионе задается параметрами СAllocationBase = 00000000, AllocationProtect = PAGE0THER State = MEM_FREE, Type = MEMPRIVA ТЕ). Д л я свободных стц
ниц не определенными остаются значения адреса и тип защиты страницы. MEM PRIVATE означает доступность этого адресного пространства только текущему процессу. Информация о закрепленном регионе задается параметрам (AllocationBase = 00010000, AllocationProtect = PAGE_READWRlTE, State = MEM_COMMIT, Type = MEM PRIVATE).
И н ф о р м а ц и я об исполнимом модуле задается параметрами (AllocationProtect = PAGE_ОTHER, State = МЕМ_С0МШТ, Туре = MEMJMAGE). Туре = MEMJMAGE о з н а ч а е т , что эта обласп
памяти может использоваться разными процессами, т.е. можно запустить несколько раз одно и то же приложение. 234
Таблица 6' Ф л а г и д л я ф у н к ц и и VirtualAlloc Назначение
Флаг МЕМ_СОММ1Т
В ы д е л я е т ф и з и ч е с к у ю память пли страничв л файл на диске
МЕМ_RESERVE
Р е з е р в и р у е т в и р т у а л ь н о е адресное прострг ство заданного р а з м е р а . Зарезервированный д и а п а з о н не м о ж е т использоваться другими функциями
МЕМ_ TOP DO WN
В ы д е л я е т с я п а м я т ь в верхней области адресного пространства
FlProtect
Т и п з а щ и т ы . Д л я физической памяти могут б ы т ь з а д а н ы ф л а г и PAGE_GUARD и PAGE_NOCACHE совместно с флагами, определенными ниже
PAGE_READONLY
Страница только для чтения. И с п о л ь з у е т с я д л я физической памяги
PAGE_READWRITE
r/w
PAGE_EXECUTE
Выполнимый
PAGE READ
г/е
EXECUTE
PAGE EXECUTE READWRITE
1 r/w/e |
PAGE_GUARD
О х р а н я е м а я ( з а щ и щ е н н а я ) страница. Любой доступ к с т р а н и ц е — ошибка
PAGE_NOACCESS
В ы к л ю ч е н доступ к странице, отраженной в физической памяти
PAGE_NOCA CHE
Не к э ш и р у е т с я с о д е р ж и м о е страницы. Используется в драйверах
PAGEJVRITECOPY
З а п и с ь в с т р а н и ц у приводит к тому, что процессу предоставляется личная копия этой с т р а н и ц ы ф и з и ч е с к о й памяти
PAGE EXECUTE WRITECOPY
1
Л ю б ы е д е й с т в и я , в т.ч. и исполнение, привод я т к ф о р м и р о в а н и ю новой копии
Атрибуты выполняемых файлов не поддерживаются операционными системами WINDOWS. Д л я них выполняемый фа' эквивалентен файлу для чтения. 236
ащаемое значение: пех — адрес памяти, габка -NULL. Обычно функция используется следующим образом. Сначаляется большой регион. Затем связывается с физической ню один небольшой блок региона. Связь с физической памя.ается только для того участка, д л я которого необходимо, ломинаем, что страницы могут быть в одном из 3-х состо• свободном — страница не зарезервирована и не связана, раницы функция VirtualAlloc может зарезервировать и л и жировать и связать; • зарезервированном — не может использоваться д р у г и м и иями выделения памяти и не имеет соответствующего фиого адреса. Функция VirtualAlloc может ее связать с физиIпамятью, но не может повторно зарезервировать. М о ж н о [Ить зарезервированные страницы ф у н к ц и е й VirtualFree; •связанном — физическая память выделена и установлены ты доступа. Система фактически и н и ц и а л и з и р у е т и за«т выделенные страницы при первой п о п ы т к е доступа к заi памяти. Когда завершается процесс, ОС освобождает все «иенные страницы. Функция VirtualAlloc м о ж е т повторно j уже связанные страницы. Ф у н к ц и я VirtualFree м о ж е т [одеть физическую память, связанную со с т р а н и ц а м и . I IpAddress !=NULL, то ф у н к ц и я VirtualAlloc и с п о л ь з у е т
!тры IpAddress и dwSize для вычисления количества требуI страниц. Если заданное число страниц не м о ж е т быть выдеК, функция завершается ошибочно. ификаторзащитыPAGE_GUARD устанавливает з а щ и т у яиц. I необходимости выделения п а м я т и д л я долгосрочного лия данных лучше выделить п а м я т ь в с т а р ш и х адресах, iworo вместо адреса начала региона задается NULL, а ф л а г RESERVE комбинируется с ф л а г о м МЕМ_ TOPDOWN. П р и
ювании памяти под регион рекомендуется задавать атрициты, наиболее общий для всего региона. Это обеспечивает лее эффективную работу системы. П р и в ы д е л е н и и вирной памяти можно задавать все атрибуты з а щ и т ы , к р о м е IEWRITECOPY, PAGE_ EXECUTE WRITECOPY, PAGE_GUARD,
EjiClCACHE — эти атрибуты можно задавать только при свявии с физической памятью. 237
Б случае успешного завершения операции выделения памяiaвыдаст сообщение <<ОК», в случае ошибки — «error». Допускается выделение памяти под отдельные записи с друлрибутом защиты. Естп размер выделяемой памяти совпадает с размером свягой памяти, то эти действия можно выполнить одним вызовом ;ии, задавая флаг, равный: MEM_RESERVE) МЕМ_СОММ1Т. В рассмотренном выше примере размер записи меньше разстраницы, поэтому в странице помещается несколько зав. Для определения необходимости выделения п а м я т и под ipyro запись используется 4 способа. . Перед попыткой записи выделяется физическая память, память уже выделена, она повторно не выделяется. Недостатратится время на выполнение функции VirtualAlloc. 2. Используя функцию VirtualQuery, узнать, передана память ает. Это еще хуже, чем первый способ — одна или две функвыполняются дополнительно. 3. Программно учитывать, выделена память или нет — к а к [идущем примере для записей 1—5. Наиболее эффективный об, но иногда трудоемкий. 4. Использовать структурную обработку исключений, если выделенной памяти (см. 11). Для возврата физической п а м я т и используется ф у н к ц и я tifree, в которой задаются: адрес начала освобождаемой памяти; размер области;
:
параметр
MEMDECGMMIT.
Если задан размер, равный 0, освобождается вся выделенная внять. Если обратиться к памяти после ее освобождения, то проI к адт ошибка доступа. Технология освобождения страниц. 1. Одна запись — одна страница. Освобождение записи — хмбождение страницы. Недостаток: не всегда совпадают раз»!(Ы. 2. Создается битовая карта занятых записей, с которой рабо•ierспециальная программа. 3. В структуре добавить поле занятости, которое может пригнать значения fme или false. Программа «сборки мусора», иеющая низкий приоритет, освобождает память под незанятые •гиги. 238
В случае успешного завершения операции выделения памямавыдаст сообщение <<ОК», в случае ошибки — «error». Допускается выделение памяти под отдельные записи с друтлрибутом защиты. Если размер выделяемой памяти совпадает с размером свяа памяти, то эти действия можно выполнить одним вызовом дни, задавая флаг, равный: MEM_RESERVE) МЕМ_СОММ1Т. В рассмотренном выше примере размер записи меньше разI страницы, поэтому в странице помещается несколько заi. Для определения необходимости выделения п а м я т и под горую запись используется 4 способа. 1. Перед попыткой записи выделяется физическая память, инамять уже выделена, она повторно не выделяется. Недоста: тратится время на выполнение функции VirtualAlloc. 2. Используя функцию VirtualQuery, узнать, передана память гет. Это еще хуже, чем первый способ — одна или две функ1 выполняются дополнительно.
3. Программно учитывать, выделена память или нет — к а к идущем примере для записей 1—5. Наиболее эффективный об, но иногда трудоемкий.
4. Использовать структурную обработку исключений, если • выделенной памяти (см. 11). Для возврата физической п а м я т и используется ф у н к ц и я 'isfree, в которой задаются: адрес начала освобождаемой памяти; размер области; параметр MEMDECGMMIT.
Если задан размер, равный 0, освобождается вся выделенная внять. Если обратиться к памяти после ее освобождения, то пропадет ошибка доступа. Технология освобождения с т р а н и ц .
1. Одна запись — одна страница. Освобождение записи — хмбождение страницы. Недостаток: не всегда совпадают разГ|1Ы. 2. Создается битовая карта занятых записей, с которой рабо'К!специальная программа. 3. В структуре добавить поле занятости, которое может при»'Матьзначения true или false. Программа «сборки мусора», юеющая низкий приоритет, освобождает память под незанятые кюгя. 239
В процессе в ы п о л н е н и я п р о г р а м м ы может потребовать i изменение атрибутов з а щ и т ы . Д л я изменения атрибутов защита связанной памяти в процессе выполнения программы используг ся функция: VirtualProtect и л и VirtualProtectEx ( п о с л е д н я я ф у н к ц и я позвс
ляет сделать изменение для заданного процесса). BOOL VirtualProtect( LPVOID IpAddress, //адрес DWORD dwSize, //размер DWORD fINewProtect, //новый атрибут защиты PDWORD IpflOldProtect //адрес переменной, куда записываете // старый атрибут
); Напоминаем, что вытеснение страниц наиболее часто выпоняется по алгоритму: вытесняется страница, которая наибате долго не использовалась. Иногда это приводит к тому, что выта няется страница, которая д о л ж н а использоваться на очередном шаге. Некоторые из страниц м о ж н о заблокировать, что иск к> чает их вытеснение во время выполнения данного процесса. Епн процесс не выполняется, заблокированные страницы могут бы, вытеснены на диск. После повторного получения кванта времени, страницы сначала будут помещены в память, а потом процесс воп становится. Д л я блокирования страниц используется функция VirtualLock. Эта ф у н к ц и я гарантирует, что при обращении к з данным страницам региона никогда не возникнет прерывания, связанного с отсутствием страницы в памяти. BOOL VirtualLock(LPVOID IpAddress,//адрес начала области DWORD dwSize //размер области
); Размер задается в байтах, но фактически блокируются одва или несколько страниц. Если для страниц задан р е ж и м PAGENOACCESS, блокири вание невозможно. По умолчанию процесс м о ж е т максимально блокировать 30 страниц. Если приложению необходимо заблокировать больше памяти, сначала оно должно вызвать функцию SetProcessWorkingSetSize д л я увеличения допустимых значений. Максимальное число страниц, которое может быть заблокировано, равно количеству страниц в его минимальной рабочей области минус маленьк и й заголовок. 240
Для разблокирования о б л а с т и и с п о л ь з у е т с я ф у н к ц и я VirtualЦсЛ. Заблокированные с т р а н и ц ы а в т о м а т и ч е с к и р а з б л о к и р у ем при завершении п р о ц е с с а . Ь Если необходимо в ы д е л и т ь б о л ь ш и е о б ъ е м ы з а к р е п л е н н о й •ити(для серверных п р и л о ж е н и й ) , м о ж н о и с п о л ь з о в а т ь н о в ы й Ь в и з м Address W I N D O W S E x t e n s i o n s ( A W E ) [ 3 , с . 3 8 7 - 3 9 7 ] . I Сброс содержимого ф и з и ч е с к о й п а м я т и о з н а ч а е т , ч т о с о д е р Ямпе области памяти м о ж е т б ы т ь у д а л е н о . И с п о л ь з у е т с я д л я Ц: и памяти, в которой х р а н и л и с ь в р е м е н н ы е з н а ч е н и я , д а л е е ||укные в программе. Н и ж е п р и в е д е н п р и м е р п р о г р а м м ы в ы Ьтя-сброса страниц п а м я т и . * elude <windows.h> Я ic!ude<stdio.h> Iretate <stdlib.h> ttneude <string.h> 'it mam mtargc, char **argv)
I
Ю1/Л/П1, -
\/irhigjfiHoc (NULL, 1024, MEM_RESERVE\MEM_COMMIT,
V MessageBox (NULL, 'Error", ' Error MB OK); I ilrcpy ((char*)pv, "aaaaaaaaaaaaaaaa"): MessageBox (NULL, (const char*)pv,"OK", MB_OK); [ ИЕсли данные дальше не нужны, то сбрасываем эту страницу I "Размер выделенной области может не совпадать с выделенной тобь узнать точный размер, вызовем I MEMORY BASICJNFORMATION mbi; I VirtualQuery (pv, &mbi, sizeof (mbi)); L/C Стажем, что эта область памяти процессу нужна, | IIчо ее содержимое не важно I VirtualAlloc (pv, mbi.RegionSize, MEM RESET, PAGE_READ WRITE); I !'Выделим всю физическую память MEMORYSTATUS ms; WGIobalMemoryStatus (&ms); I PVOIDpv1 = VirtualAlloc (NULL, ms. dwTotalPhys, MEM_RESERVE\MEM_COMMIT, PA GE_ READ WRITE); /(pv1 —NULL) ГMessageBox (NULL, "Error" "Error", MB_OK); I esef I ZeroMemory 'pv1, ms. dwTotalPhys); • MessageBo* (NULL, (const char*)pv,"OK" MB OK ); return 0;
241
С н а ч а л а в ы д е л я е т с я п а м я т ь размером 1024 байта (фа? тически 4096) и туда копируется заданная строка. Чтобы ска зать системе, что страницу м о ж н о сбрасывать, устанавливая^ MEM_RESET. При повторном обращении к этим страницам там может быть у ж е мусор!!! Попытка полного выделения памяти жет быть удачной и неудачной. При удачном выделении сод мое памяти для сбрасываемой страницы может измениться. Файлы, проецируемые в память
В о т л и ч и е от в и р т у а л ь н о й п а м я т и , которой всегда со^ ветствует страничный файл, отображаемой памяти соответсщгет реальный файл. Используется при интенсивном обращеыи к файлу. К а к только файл отображен на память, можно считать, что он весь в памяти. Когда нужно использовать? 1. Загрузка и выполнение исполняемых файлов — врех* уменьшается за счет того, что не требуется копирование неполнаемого файла в память. 2. Доступ к файлу КЭ.К К обычной памяти — время уме» шается, так как ОС выполняет управление памятью в ваибо.*'* эффективном режиме. 3. Р а з д е л е н и е д а н н ы х м е ж д у несколькими процесса*! Объект «Отображаемый файл (File Mapping)» является об кг* ядра, хранится в п а м я т и , доступной всем процессам, и можг иметь и м я , по которому процессы обращаются к нему. 1. П р о е ц и р о в а н и е в п а м я т ь исполняемых файлов (ЕХЕ DLL). При создании нового потока (функция CreateProcess) вь полняет действия: — отыскивает исполняемый файл, связанный с процессом, если нет — ошибка; — создает новый объект я д р а «Процесс»; — создает новое адресное пространство для процесса (4 Гбайт I — резервирует регион д л я размещения исполняемого фи.и (обычно адрес начала и размер хранятся в самом исполвяем и файле; загрузчик, если это возможно, оставляет данный адрес!. — отмечает, что это файл на диске, а не в памяти. При загрузке DLL ( ф у н к ц и я LoadLibrary) выполняются де»ствия: — отводится регион для этой библиотеки. Библиотеки моцт быть модулями типа FIXED, т.е. не настраиваемыми, а значит 242
®<>ны быть расположены, начиная с заданного адреса. Если сияние уожет выделить эту память — ошибка; -отмечает, что в ы д е л е н н а я п а м я т ь с в я з а н а с р е а л ь н ы м ф а й I. вне со страничным ф а й л о м . Использование
одного
экземпляра
кода
для
нескольких
про-
к Ecui запустить программу и до ее завершения запустить ее во, код используется один и тот же. Данные, определенные во •юней области, сформированные одной задачей, могут мешать ^штьному выполнению другой задачи. Поэтому ОС использует наш случае «копирование при записи», т.е. выделение новой • л для изменяемого модуля. Рассмотрим пример использования этого р е ж и м а . Пусть задана база ключевых данных, в которой данные хра<гм в формате: '
Всего ключей (4 байта), Ключ 1, Ключ 2, ... Каждый ключ задается в в и д е : Длина ключа (4 байта) Сам №
IIvcTb ключи должны читаться в произвольном порядке. Если файл с ключами достаточно большой, т.е. хранение ia в памяти целиком не желательно, время доступа к ключу «легбыть большим. Для решения подобных задач применяется енпе файла на память. Алгоритм использования проецируемых в память файлов: 1. Создать или открыть объект ядра «Файл». 2. Создать объект ядра «Проекция файла». 3. Связать объекты и у к а з а т ь , к а к а я ч а с т ь ф а й л а б у д е т о т р а в проекции.
4. После выполнения требуемых действий отменить проецие. 5. Удалить объекты «Проекция файла» и «Файл». Пример доступа к ключу с заданным номером. SineЫв <windows.h> Mude <string.h> iinclude <stdic.h>
bocl KeyDataWrite (LPCSTR IpFileName, DWORD dwKeysCount) i DWORD dwLen; boot bRetValue = true;
//Определение требуемой длины ключевых данных 243
dwLen = 4; DWORD i; //Предположим, что длина ключа равна его номеру +1 for (i = О; i < dwKeysCount; i++) { dwLen +=4 + i + 1;
} //1. Создать или открыть объект ядра «файл» HANDLE h = INVALID_HANDLE_VALUE; HANDLE hFileMapping = 0; LPVOID IpMem = 0; —try{ h = CreateFile ( IpFileName, GENERIC_ WRITE\GENERIC_READ, 0, 0. CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); i (h == INVALID_HANDLE_VALUE){ bRetValue = false; return false;
}
//2. Создать объект ядра «проекция файла» DWORD flProtect = PAGE_READWRITE; DWORD dwMaximиmSIzeHigh = 0; DWORD dwMaximumSizeLow = dwLen; hFileMapping = CreateFileMapping (h, 0, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow. 0); if (hFileMapping -= 0){ bRetValue = false; return false;
}
//3. Связать объекты и указать, какая часть //файла будет отражена в проекции. DWORD dwDesiredAccess = FILЕ_MAР_WRIТЕ; DWORD dwFileOffsetHigh = 0; DWORD dwFileOffsetLow = 0; DWORD dwNumberOfBytesToMap = dwLen; LPVOID IpMem = MapViewOfFile( hFileMapping, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap
);
if (IpMem == 0){
}
// Заполнение
bRetValue = false; return false; ключевых данных 244
'(DWORD')lpMem = dwKeysCount; BYTE *bMem = (BYTE ') IpMem, *bCurMem = bMem + 4; DWORD i,j; for (i = 0;i< dwKeysCount; i++) (
} }
%DWORD*) (bCurMem)=i+ 1; bCurMem += 4; for (j - 0; j < i + 1;j++) bCurMem[j] = (i + 1)%10 + V; bCurMem+=j;
finally Г
114. После выполнения требуемых действий IIотменить проецирование. if(lpMem){ UnmapViewOfFile( IpMem); IpMem = 0;
} 115. Удалить объекты «проекция файла» и «файл», if (hFileMappIng )( CloseHandle (hFileMapping); hFileMapping = 0;
}
if(h <= INVALID_HANDLE_VALUE){ CloseHandle (h); h = INVALID_HANDLE_VALUE;
} }
return bRetValue;
'00/KeyDataRead (LPCSTR IpFileName, DWORD dwKeyNumber, LPVOID IpKey, DWORD &dwLen) DWORD dwKeysCount; boot bRetValue - true; HANDLE h = INVALIDHANDLEVALUE; HANDLE hFileMapping = 0; LPVOID IpMem = 0; h = CreateFile (IpFileName, GENERIC_READ, 0, 0, CPEN_EXISTING, FILE ATTRIBUTE_NORMAL, 0); if(h == INVALID_HANDLE_VALUE){ bRetValue = false; return false;
} 245
DWORD flProtect = PA GE_ READ ONLY; DWORD dwMaximumSizeHigh = 0; DWORD dwMaximumSizeLow = 0; hFileMapping = CreateFileMapping (h, 0, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, 0); if (hFileMapping == 0){ bRetValue = false; return false;
} DWORD DWORD DWORD DWORD LPVOID
dwDesiredAccess = FILE_MAP_READ; dwFileOffsetHigh - 0; dwFileOffsetLow = 0; dwNumberOfBytesToMap = 0; IpMem = MapViewOfFilef hFileMapping, dwDesiredA ccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap
); if (IpMem == 0){ bRetValue = false; return false;
}
dwKeysCount = *(DWORD*)lpMem; if (dwKeyNumber >= dwKeysCount){ bRetValue = false; return bRetValue;
}
BYTE *bMem = (BYTE *) IpMem, *bCurMem = bMem + 4; DWORD i.j; DWORD dwCurLen; for (i = 0; i < dwKeyNumber; i++) { dwCurLen = *(DWORD*) (bCurMem); if (dwCurLen == 0){ bRetValue = false; return bRetValue;
}
bCurMem += 4 + dwCurLen;
} dwLen = *(DWORD*)bCurMem; bCurMem+=4; if(lpKey) 246
тетеру (IpKey, bCurMem, dwLen);
}
finally
Г
if(lpMem){ UnmapViewOfFile( IpMem ); IpMem = 0;
}
if (hFileMapping ){ CloseHandle (hFileMapping); hFileMapping = 0;
}
if(h != INVALID. HANDLE^VALUE ){ CloseHandle (h); h = INVALID_HANDLE_VALUE;
}
}
return bRetValue; Htnainfll
boolb = KeyDataWrite ("Keys.dat5); ЦЬ) printf ("KeyDataWrite: OK\n"); else printf ("KeyDataWrite: Error\n"); DWORD dwLen; b = KeyDataRead ("Keys.dat", 4, 0, dwLen); M printf ("KeyDataRead:OK\ndwLen = %d\n", dwLen); BYTE *bKey = new BYTE[dwLen + 1]; bKey[dwLen] = 0; KeyDataRead ("Keys.dat", 4 , bKey, dwLen); printf ("%s\n" bKey); delete[]bKey;
}
else printf ("KeyDataRead:ErroAn"); return 0; При изучении примера о б р а т и т е в н и м а н и е на с л е д у ю щ е е : - особенности и с п о л ь з о в а н и я ф у н к ц и и CreateFile для нового »ушествующего файлов; -дескриптор файла п р и и с п о л ь з о в а н и и ф у н к ц и и Create- 'Mapping в случае н е у д а ч и р а в е н 0, а не INVALIDJHANDLE_ Wtt/f, как для функции CreateFile; - использование ф у н к ц и и MapViewOfFile для н о в о г о и с у щ е т'ющего файлов; 247
— определение длины ключа с целью выдечеиня памп» В данном случае адрес памяти равен 0, пока длина кчгоча вествя. Такой прием ОС использует часто, если невоэмо,». >МН нее определить требуему ю память под результат. — использование finally для корректного выполнения чения памяти и закрытия файлов. Рассмотрим теперь испольжвание проекций файла ера, —« процессах. Для совместного использования данных в каждом П]« I необходимо: Создать файл (CreateFile); Создать его проекцию (CreateFileMapping): Связать проекцию с памятью (MapViewOfFiIe и.тп Мбр1 » OfFileEx). Если файл у ж е создан другим процессом, он заново вt дается, а создается его проекция на адресное пространстве:» процесса, в результате связывания с памятью отражается ы •*» и те же физические адреса. Заметим, что после выполнения функции CreateF *Мчр можно узнать, создался новый объект И Ч И нет. ФУНКЦИЯ бЯ."» Error возвращает ERRORALREADY EXIST при неошибочш • скрнпторе, если проекция у ж е существует, надо только увелмИ счетчик. Вместо функции CreateFileMapping можно неполной • функцию OpenFileMapping, если наверняка уже проекцЦ дана. В случае отсутствия проекции функции 0p8f)FeM«>* завершается с ошибкой. В качестве имени открываемого ф*1» . используется имя. полученное в функции CreateFifeMapping. При наличии родственных зависимостей между процеаис можно использовать наследование. Родительский процесс создает объект, который можв". • следовать. Процесс-потомок наследует атот объект. Для соам* наследуемой проекции файла в функции CreateFileMap. тд ни ходимо задать структуру SEQURITY^A TTRIBUTES: SEQURITY ATTRIBUTES за se nLength = sizeof (sa); sa.lpSequrilyDescriptor = NULL; sB.blnherityHandle = TRUE. hFileMapping = CreeteFiteMappmg (h. &sa..~).
[ создания п р о ц е с с а - п о т о м к а и с п о л ь з у е т с я ф у н к ц и я Process, в которой п а р а м е т р plnherityHandle = TRUE. Сам дескриптор проекции м о ж н о п е р е д а т ь п р о ц е с с у - п о т о м •шример, через список п а р а м е т р о в п р о г р а м м ы . Особенности проекции на физическую память из странич»файла Пусть данные, которые н у ж н о р а з д е л я т ь , н а х о д я т с я в п а м я I, г талисывать их на диске не н у ж н о . К а к их р а з д е л и т ь ? В этом случае функция CreateFile не в ы з ы в а е т с я , а в ы з ы гся прямо CreateFileMapping и в к а ч е с т в е д е с к р и п т о р а ф а й л а иется Oxffffffff. Объем в ы д е л я е м о й п а м я т и д л я э т о г о ф а й л а [пегается параметрами р а з м е р а ( с т а р ш а я и м л а д ш а я ч а с т и ) , связи ее с физической п а м я т ь ю ( ф у н к ц и я MapViewOfFile) ) использовать как о б ы ч н ы й р е г и о н . Е с л и н е о б х о д и м о искать в других процессах, з а д а е т с я и м я ф а й л а в ф у н к ц и и РШзрртд. В конце необходима ф у н к ц и я CloseHandle. Частичная передача памяти проецируем файлам Если нужно не всему ф а й л у п е р е д а т ь п а м я т ь , а т о л ь к о е г о % ч, в функции CreateFileMapping в п а р а м е т р е fdwProtect н у ж н о шьзначение SEC_RESERVE и л и SEC_COMMIT. ^и флаги используются т о л ь к о т о г д а , е с л и п р о е к ц и я ф а й л а дует страничный файл. П а р а м е т р SEC_COMMlT о з н а ч а е т , t :|йзу выделяется память в с т р а н и ч н о м ф а й л е (этот ф л а г по , по флагу SEC_COMMIT п а м я т ь с р а з у не в ы д е л я е т с я . ! при вызове функции MapViewOfFile и л и MapViewOfFileEx ь все еще не выделяется, о б р а щ е н и е к э т о й о б л а с т и п а м я т и «шибку. Для распределения ф и з и ч е с к о й п а м я т и и с п о л ь з у е т шшия VirtualAlloc (см. 6.4.3). «Кучи» Третий и последний м е х а н и з м у п р а в л е н и я п а м я т ь ю — исние «кучи» (heaps). И с п о л ь з у ю т с я п р и н е о б х о д и м о с т и «небольшими массивами д а н н ы х . Характеристика «кучи». «Куча» всегда может использоваться т о л ь к о о д н и м п р о ц е с с о м . Один процесс может иметь н е с к о л ь к о « к у ч ». DLL не выделяет собственной « к у ч и » , о н а и с п о л ь з у е т « к у ч у » , который ее вызвал. DLL м о ж е т с о з д а т ь « к у ч у » д л я себя •сном пространстве процесса, в ы з в а в ш е г о ее. 249
Определение о кучи». « К у ч а » — э т о з а р е з е р в и р о в а н н ы й ( н е закрепленный.) с т о к а д р е с н о г о п р о с т р а н с т в а . П о м е р е и с п о л ь з о в а н и и згой п а к т ( h e a p m a n a g e r ) д и с п е т ч е р • к у ч и » з а к р е п л я е т з а ней н»ияп й с т р а н и ч н о г о ф а й л а . П р и о с в о б о ж д е н и и п а м я т и диспетчер «"«"ii I возвращает страницы системе. Стандартная «кучи» процесса. П р и с о з д а н и и п р о ц е с с а ОС с т а в и т е м у в соответствие стон | д п р т н у ю « к у ч у » ( p r o c e s s ' s d e f a u l t h e a p ) р а з м е р о м 1 Мба п а р а м е т р м о ж н о п е р е о п р е д е л и т ь в к о м а н д н о й строке к о » - » гцика и л и в с р е д е . С а м и ф у н к ц и и W I N 3 2 используют «к п о э т о м у у м е н ь ш а т ь р е а м е р н е с т о и т . Д и с п е т ч е р «кучи» с * г ва т е м , ч т о б ы о т д е л ь н ы е п о т о к и о д н о в р е м е н н о не имели дс . к «куче». При этом используется п р и н ц и п посчедоваия I д о с т у п а : с н а ч а л а п е р в ы й п о т о к и с п о л ь з у е т , а второй ждет, м » с л е д у ю щ и й и т.д. Е с л и есть о д и н процесс, ему лучше вы с в о ю « к у ч у * , ч т о б ы н е б ы л о к о н ф л и к т о в с ф у н к ц и я м и WINSii ф у н к ц и и в с е г д а и с п о л ь з у ю т с т а н д а р т н у ю к у ч у ) . Стенда} « к у ч у * с о з д а е т с а м а О С и у н и ч т о ж а е т о н а е е с а м а . Дескр-.i с т а н д а р т н о й « к у ч и » в о з в р а щ а е т ф у н к ц и я GetPfOCessHeap: HANDLE
GetProcessHeapfVOID)
П р и у с п е ш н о м з а в е р ш е н и и ф у н к ц и я в о з в р а щ а е т дескриг», « к у ч и » в ы з ы в а ю щ е г о п р о ц е с с а . В с л у ч а е о ш и б к и фувкп * m в р а щ а е т NULL. Д е с к р и п т о р с т а н д а р т н о й « к у ч и * м о ж н о использовать. в ы д е л е н и я п а м я т и с п о м о щ ь ю ф у н к ц и и HeapAlloc (GetProсм И вар(). О, dwByteS). Н а п о м и н а е м , ч т о э т о т д е с к р и п т о р не надо тп о л ь з о в а т ь в ф у н к ц и и HeapDestroy. К р о м е « к у ч и » , п р е д у с м о т р е н н о й п о у м о л ч а н и ю , нож- и п о л ь з о в а т ь д о п о л н и т е л ь н ы е о б л а с т и п а м я т и ( « к у ч и » ) . Испслш в в н и е о т д е л ь н ы х « к у ч » д л я л о г и ч е с к и о т д е л ь н ы х элемента* »»• граммы позволяет упростить отладку программы. Пример. П у с т ь в п р о г р а м м е и с п о л ь з у ю т с я дерево я со К а ж д ы й э л е м е н т д и н а м и ч е с к и и з м е н я е т с я , и для их постр«п и с п о л ь з у е т с я о б щ а я « к у ч а » . В х о д е в ы п о л н е н и и программы л а с т и п а м я т и д л я о б е и х д и н а м и ч е с к и х с т р у к т у р в памяти б>#п е р е с е к а т ь с я . В с л у ч а е о ш п б к п п р и р а б о т е с о д н о й дивемичесил с т р у к т у р о й в о з м о ж н а н е в е р н а я з а п и с ь д л я д р у г о й . Это с ч е т а труднит отладку программы. 250
Кроме этого, если память в ы д е л я е т с я — о с в о б о ж д а е т с я одними порциями, то вероятность ф р а г м е н т а ц и и п а м я т и у м е н ь ем я, что увеличивает э ф ф е к т и в н о с т ь р а с п р е д е л е н и я п а м я т и . И, шонец, если локальная «куча» н е б о л ь ш о г о р а з м е р а , то веро•'Зстьтого, что она в оперативной п а м я т и з н а ч и т е л ь н о в ы ш е , «лябольшой «кучи». Как создать н о в у ю « к у ч у » д л я п р о ц е с с а ? Создание Win32 «кучи» Для создания используется ф у н к ц и я HeapCreate: Функция выделяет н е п р е р ы в н ы й б л о к п а м я т и в в и р т у а л ь в v •адресном пространстве т е к у щ е г о п р о ц е с с а и в ы д е л я е т ф и з и *! по память для начального блока в ы д е л е н н о й п а м я т и . HANDLE HeapCreate( WORD «Options,
//Флаги
DWORD dwImtialSize
II Размер
DWORD dwMaximumSize
начального
I/Максимальный
блока размер
«кучи»
HOptions — определяет а т р и б у т ы н о в о й « к у ч и » . Д е й с т в у е т i^Bf "якцпй, использующих «кучу» (HeapAlloc, HeapFree, НеарkAmC,nHeapSize). Можно задать о д и н и л и н е с к о л ь к о ф л а г о в : HEAPJGENERATE_EXCEPTIONS — у к а з ы в а е т , ч т о система будет формировать и с к л ю ч е н и е в с л у ч а е о ш и б о к , т а к и х как нехватка памяти, вместо в о з в р а т а N U L L . HEAP_NO_SERIALIZE — о п р е д е л я е т р е ж и м м о н о п о л ь н о г о использования «кучи» п о т о к а м и п р о ц е с с а . По у м о л ч а н и ю этот флаг не задан, д о п у с к а е т с я о д н о в р е м е н н ы й д о с т у п двух потоков к «куче». dwInitialSize — определяет н а ч а л ь н ы й р а з м е р б л о к а в б а й т а х . In*™ выравнивается на г р а н и ц у с т р а н и ц ы с а м о й ф у н к ц и е й . dwMaximumSize — если м а к с и м а л ь н ы й р а з м е р н е н у л е в о й , » максимальный размер в б а й т а х ( в ы р а в н и в а е т с я на г р а н и ц у тсицысамой функцией). Если р а з м е р п а м я т и , з а д а н н ы й ф у н к вии HeapAlloc или HeapReAlloc п р е в о с х о д и т н а ч а л ь н ы й р а з м е р
251
ч е м 0 x 7 F F F 8 б а й т м о г у т не б ы т ь о ш и б о ч н ы м и ; система вы ф у н к ц и ю VirtualAlloc д л я п о л у ч е н и я т а к и х блоков памяти. П м у е с л и п р и л о ж е н и ю н е о б х о д и м ы б о л ь ш и е б л о к и памяти dwl.'irmumSize = 0. Возвращаемое значение. Успех — дескриптор области памяти. О ш и б к а — NULL. (GetLastError.) З а м е ч а н и е . П р о ц е с с у д о с т у п н о не все выделенное прос ство — е с т ь е щ е с л у ж е б н а я и н ф о р м а ц и я (заголовки). При зад,- ни максимального размера к у ч и их надо учитывать. Алгоритм выделения памяти из кучи: — ОС п р о с м а т р и в а е т с в я з а н н ы й с п и с о к свободных и заняты блоков; — н а х о д и т а д р е с н а ч а л а п е р в о г о д о п у с т и м о г о свобод | г блока; — в ы д е л я е т н о в ы й б л о к , п о м е ч а я свободный блок как тый; — к о р р е к т и р у е т с п и с о к с в о б о д н ы х и з а н я т ы х блоков. Е с л и ф л а г HEAP_NO_SERIALIZE не установлен (по у i.niн и ю ) , это о з н а ч а е т , ч т о д о с т у п к « к у ч е » в многопоточном щш л о ж е н и и в с е г д а п р а в и л ь н ы й , но не всегда оптимальный » с л у ч а е з а п р о с п о т о к а на п а м я т ь в ы п о л н я е т с я до конца, в т до корректировки списка. Е с л и ф л а г HEAPJNOJSERIALIZE у с т а н о в л е н , запрос н л е н и е м о ж е т б ы т ь п р е р в а н в л ю б о й м о м е н т . В этом случае т о к а м о г у т н а й т и о д и н и тот же н е з а н я т ы й б л о к , т.е. «куча» f испорчена. Ф л а г м о ж н о устанавливать, если: -— в п р о ц е с с е т о л ь к о о д и н п о т о к и л и с «кучей» работает: » ко один; — п о т о к с а м у п р а в л я е т с и н х р о н и з а ц и е й работы с памя i Выделение блока п а м я т и из «кучи» Ф у н к ц и я НеарАПос: LPVOID НеарА11ос( HANDLE hHeap, DWORD dwFlags, DWORD dwBytes );
// дескриптор личного блока («кучи») //флаги // количество выделенных байт
П а м я т ь в ы д е л я е т с я в п е р е м е щ а е м о й области. 252
Mags — определяет ф л а г и , к о т о р ы е более п р и о р и т е т н ы , фаги при создании «кучи». Можно задавать флаги: HEAP_GENERATE_EXCEPTIONS, HEAP_NO_SERIALIZE, HEAP ZERO MEMORY — з а п о л н и т ь в ы д е л е н н у ю п а м я т ь г,-«.Заметим, что если флаг HEAP_ZERO_MEMORYне у с т а н о в ят выделенная память не и н и ц и а л и з и р у е т с я . dwBytes — количество в ы д е л е н н ы х б а й т . Е с л и « к у ч а » з а д а н а и- «растущая «куча», dwBytes < 0 x 7 F F F 8 . Возвращаемое значение. Успех — адрес начала в ы д е л е н н о й п а м я т и . Ошибка и не задано HEAP GENERA ТЕЕХСЕР TIONS, ф у н к Кивращает NULL, а если задано, ф у н к ц и я г е н е р и р у е т и с к л ю и.е, которое программист м о ж е т о б р а б о т а т ь : STATUS_NO_MEMORY — п о п ы т к а р а с п р е д е л е н и я п о т е р п е л а г:ачу из-за недостатка д о с т у п н о й п а м я т и и л и р а з р у ш е н н о й •'ГШ».
STATUS_ACCESS_VIOL ATI ON — п о п ы т к а р а с п р е д е л е н и я • г,, пела неудачу из-за плохой « к у ч и » и л и н е в е р н ы х п а р а м е т р о в | ыиви.
То или другое исключение в с л у ч а е п л о х о й « к у ч и » з а в и с и т • ;;,:чшыразрушения «кучи». Вслучае ошибки ф у н к ц и я не в ы з ы в а е т SetLastError, п о э т о м у чг^жение не может вызвать GetLastError д л я п о л у ч е н и я и н ф о р u ив об ошибке. Замечание. В случае успешного з а в е р ш е н и я ф у н к ц и и Н е а р Ц.г она выделяет, по меньшей м е р е , з а т р е б о в а н н о е к о л и ч е с т в о 4*.
Определение размера п а м я т и Чтобы узнать действительный р а з м е р в ы д е л е н н о й п а м я т и , • юьзуется функция HeapSize. Ф у н к ц и ю м о ж н о и с п о л ь з о в а т ь а*-е функций НеарАНос или HeapReAlloc. DWORD HeapSizef HANDLE hHeap, DWORD dwFlags,
//дескриптор «кучи» // флаги
LPCVOID IpMem
//адрес блока памяти, ляется
для которого опреде-
размер
I.
M a g s — дополнительные х а р а к т е р и с т и к и и с п о л ь з у е м о г о Ьма (дока используется только о д и н б и т , о с т а л ь н ы е з а р е з е р в и I и ы)' 253
HEAP_N0 SERIALIZE Возвращаемое значение: Успех — размер в байтах. О ш и б к а — OxFFFFFFFF. Ф у н к ц и я не вызывает
SetLastEry
Освобождение п а м я т и Д л я о с в о б о ж д е н и я и с п о л ь з у е т с я ф у н к ц и я HeapFree. П а м я т ь , в ы д е л е н н а я НеарАНос, не перемещаемая, поэ~г эта о б л а с т ь п а м я т и д о л ж н а б ы т ь н е ф р а г м е н т и р о в а н о й . Возвращаемое значение: У с п е х — TRUE; О ш и б к а — FALSE У н и ч т о ж е н и е «кучи» Ф у н к ц и я HeapDestroy: Ф у н к ц и я освобождает п а м я т ь . BOOL HeapDestroy( HANDLE hHeap //дескриптор «кучи» У. Возвращаемое значение: У с п е х — не н о л ь . О ш и б к а — н о л ь (GetLastError). П р о ц е с с м о ж е т в ы з в а т ь ф у н к ц и ю HeapDestroy без предмрт е л ь н о г о в ы з о в а ф у н к ц и и HeapFree. Н а п о м и н а е м , что стаид»рную «кучу» у н и ч т о ж а т ь не надо! И н ф о р м а ц и я о «кучах» Д л я п о л у ч е н и я и н ф о р м а ц и и о в с е х « к у ч а х » использует ф у н к ц и я DWORD GetProcessHeaps: Эта ф у н к ц и я п о з в о л я е т п о л у ч и т ь д е с к р и п т о р ы всех д л я текущего процесса. DWORD GetProcessHeaps( DWORD NumberOfHeaps, //максимальное количество Н дескрипторов PHANDLE ProcessHeaps // адрес начала массива дескриптора ); NumberOfHeaps — м а к с и м а л ь н о е количество дескриптор» для которых может быть получена информация. В о з в р а щ а е м о е з н а ч е н и е : в о з в р а щ а е т количество действ\т щ и х дескрипторов д л я процесса. Е с л и в о з в р а щ а е м о е з н а ч е н и е м е н ь ш е , чем NumberOfHe I* и л и р а в н о е м у , о н о я в л я е т с я д е й с т в и т е л ь н ы м количество] скрипторов. 254
Если возвращаемое з н а ч е н и е б о л ь ш е , ч е м NumberOfHeaps, т о заново выделить д о с т а т о ч н у ю п а м я т ь и з а н о в о повто:i вызов функции. Если возвращаемое з н а ч е н и е р а в н о 0, ф у н к ц и я о ш и б о ч н а Iгюг).
GetProcessHeap п о з в о л я е т п о л у ч и т ь д е с к р и п т о р 'иной «кучи» текущего п р о ц е с с а . Пример. ФУНКЦИЯ
HANDLE hHeapsf25]; DWORD
dwHeaps
=
GetProcessHeaps
(25,
hHeaps);
< dwHeaps>25){ |
p Увеличить размерность
массива
hHeaps;
elsef //Вывести
dwHeaps
элементов
дескрипторов
I Проверка целостности «кучи» Для проверки целостности « к у ч и » и с п о л ь з у е т с я ф у н к ц и я pVafcfale: Функция сканирует все б л о к и п а м я т и « к у ч и » , п р о в е р я е т гтьность всего списка. М о ж н о п р о в е р и т ь ц е л о с т н о с т ь е д и н юго блока памяти, а не всей « к у ч и » . BOOt HeapValidatef HANDLEhHeap,
//дескриптор
DWORDdwFlags,
//флаги
LPCVOID
IpMem
//указатель
«кучи» на
для
проверки
индивидуальный
блок
памяти
I
Допустимые значения флагов: HEAP_NO_SERIALIZE IpMem - может быть равен NULL. Е с л и IpMem = NULL, то дия проверяет целостность всей « к у ч и » , е с л и IpMem = NULL, «функцияпроверяет целостность з а д а н н о г о б л о к а . Возвращаемое значение: не ноль, если целостность не н а р у ш е н а . Если нарушена, функция в о з в р а щ а е т 0. П р и э т о м на э к р а н ится сообщение о н а р у ш е н и и ц е л о с т н о с т и . Ф у н к ц и я не замет информацию об ошибке. Для каждого блока п а м я т и есть с т р у к т у р а с и н ф о р м а ц и е й • т е . Функция проверки п р о в е р я е т с о о т в е т с т в и е б л о к о в заго-
255
Объединение свободных блоков Ф у н к ц и я HeapCompact Ф у н к ц и я о б ъ е д и н я е т с в о б о д н ы е б л о к и и возвращает ОС ев" бодные страницы. UINT HeapCompact ( HANDLE hHeap, //Дескриптор «кучи» compact DWORD dwFlags // Флаги ); dwFlags — HEAP NO SERIALIZE Возвращаемое значение: У с п е х — з н а ч е н и е в б а й т а х н а и б о л ь ш е г о свободного блока О ш и б к а — 0 (GetLastError). В с л у ч а е о т с у т с т в и я свободного п р о с т р а н с т в а функция вс>• в р а щ а е т 0, и ф у н к ц и я GetLastError в о з в р а щ а е т NO_ERROR. Н е т г а р а н т и и , ч т о м о ж н о будет в ы д е л и т ь заданный объем памяти. С и н х р о н и з а ц и я п о т о к о в с т о ч к и з р е н и я используемой «кучи» « К у ч а » — д о с т а т о ч н о г и б к и й и н с т р у м е н т , д л я которого (X м о ж е т с а м а в ы п о л н я т ь с и н х р о н и з а ц и ю (по умолчанию) пли в е р и т ь » это п о л ь з о в а т е л ю (см. ф л а г HEAP_NO_SERIALIZE). Ра. с м о т р и м о с о б е н н о с т и « р у ч н о г о » у п р а в л е н и я «кучей» в режш многопоточного использования. Ф у н к ц и и HeapLock, HeapUnlock: П о с л е в ы з о в а ф у н к ц и и HeapLock т е к у щ и й поток становий1 е д и н с т в е н н ы м в л а д е л ь ц е м « к у ч и » . Все д р у г и е потоки, испо ю щ и е « к у ч у » , б л о к и р у ю т с я д о в ы з о в а ф у н к ц и и HeapUnlock. BOOL HeapLock ( HANDLE hHeap // дескриптор «кучи» ); Возвращаемое значение: Если ф у н к ц и я з а в е р ш и л а с ь успешно — не 0. Е с л и о ш и б к а — то 0 (См. GetLastError). BOOL HeapUnlock( HANDLE hHeap
//дескриптор «кучи»
); Возвращаемое значение: У с п е х -— не н о л ь . О ш и б к а — 0 (GetLastError). 256
6.5. Вопросы и з а д а ч и | Что такое копирование только п р и з а п и с и ( c o p y - o n - w r i t e ) ? В каком случае целесообразно использовать э т о т р е ж и м ? .. Как вычисляется адрес п а м я т и в р е а л ь н о м р е ж и м е ? О п р е д е л и т е диапазон изменения адреса д л я этого р е ж и м а . 1 Как вычисляется адрес п а м я т и в з а щ и щ е н н о м р е ж и м е ? О п р е д е лите диапазон изменения а д р е с а д л я э т о г о р е ж и м а . I. За счет чего обеспечена з а щ и т а п а м я т и в з а щ и щ е н н о м р е ж и м е ? 1. Что такое FLAT-модель? К а к и е д о с т о и н с т в а и н е д о с т а т к и и м е е т эта модель по сравнению с с е г м е н т н о й а д р е с а ц и е й ? 6. Определите алгоритм п р е о б р а з о в а н и я л о г и ч е с к о г о а д р е с а в физический при двухуровневой с т р а н и ч н о й а д р е с а ц и и . ' Что такое большие страницы? П о ч е м у т а к и е с т р а н и ц ы не используются в пользовательском р е ж и м е ? к. Каким образом определяются с т р а н и ц ы д л я в ы г р у з к и в с л у ч а е нехватки свободной физической п а м я т и ? 0 Что такое пробуксовка? 1С. Для чего используется кэш-память? О п р е д е л и т е а л г о р и т м о п р е деления места в кэше для з а д а н н о г о а д р е с а . К Реализуйте алгоритм LRU, и с п о л ь з у е м ы й д л я о п р е д е л е н и я блока, данные которого вытесняются из к э ш а . 2 Реализуйте программу определения п а р а м е т р о в к э ш а . Д л я ч е г о необходимо определять эти п а р а м е т р ы ? I? Реализуйте алгоритм « б л и з н е ц о в » д л я в ы д е л е н и я о б л а с т е й памяти. Проанализируйте в о з м о ж н о с т ь ф р а г м е н т а ц и и п а м я т и вслучае использования этого а л г о р и т м а .
Н. Что такое регион памяти? 15. Какую информацию о памяти м о ж н о п о л у ч и т ь с п о м о щ ь ю ф у н к ции GetSystemlnfo? Изучите п о м о щ ь по э т о й ф у н к ц и и по M S D N . 16. Изучите состояние виртуальной и ф и з и ч е с к о й п а м я т и с п о м о щью функций GlobalMemoryStatusEx, VirtualQueryEx. !7. Изучите функцию VirtualAlloc. Р е а л и з у й т е ф у н к ц и ю д л я выделения памяти под записи с з а д а н н ы м и н о м е р а м и . П а м я т ь п о д запись должна выделяться только в т о м с л у ч а е , е с л и о н а р а н е е аебыла выделена. И Вкаком случае целесообразно о т о б р а ж а т ь ф а й л на п а м я т ь ? 19. Составьте функции для чтения из ф а й л а з а п и с е й с з а д а н н ы м и номерами, если размер всех з а п и с е й о д и н а к о в . В п е р в о й ф у н к ции для позиционирования в ф а й л е и с п о л ь з о в а т ь ф у н к ц и ю S e f FilePointer. Во второй ф у н к ц и и использовать о т о б р а ж е н и е ф а й л а на память. Сравнит, среднее время д о с т у п а к о д н о й з а п и с и д л я каждой функции. А Используя отображение файла на п а м я т ь , в ы д е л и т е о б щ у ю память для нескольких процессов.
57
21. В к а к о м с л у ч а е и с п о л ь з у ю т с я «кучи»? 2 2 . Ч т о т а к о е с и с т е м н а я «куча»? В к а к о м с л у ч а е приложение е т с в о ю «кучу»? 2 3 . Р е а л и з у й т е п р о г р а м м у , в к о т о р о й и с п о л ь з у ю т с я двоичное до и с в я з н ы й с п и с о к . Д л я к а ж д о й д и н а м и ч е с к о й структуры вд е л и т е с в о ю « к у ч у » . Ч т о д а е т и с п о л ь з о в а н и е индивпдуальп.Л «кучи» д л я о т д е л ь н ы х с т р у к т у р ?
258
7. УПРАВЛЕНИЕ У С Т Р О Й С Т В А М И
Цели изучения раздела: Обменить ключевые различия между последовательными и параллельными устройствами. I. Описоть отношения между аппаратным обеспечением и логическими устройствами, обеспечиваемыми О С . 3 Описоть буферизацию и стратегии ее использования. i Привести различия между механизмами, используемыми для взаимодействия с устройствами компьютера (включая сетевую аппаратуру, мультимедиа и т.д.) и объяснить влияние этих различий на проектирование ОС. ) Описать преимущества и недостатки прямого доступа к памяти и условия, в которых прямой доступ к памяти оправдан. 6. Определить требования к восстановлению после сбоев. 7. Реализовать простой драйвер для ряда устройств.
7.1. Управление устройствами Все внешние у с т р о й с т в а м о ж н о р а з д е л и т ь н а п о с л е д о в а • ~вые н параллельные. К п о с л е д о в а т е л ь н ы м ( с и м в о л ь н ы м ) гтрсАствам относятся у с т р о й с т в а д л я п о с и м в о л ь н о й п е р е д а ч и , порядок передачи с и м в о л о в и м е е т з н а ч е н и е . К СИМВОЛЬНА устройствам о т н о с и т с я к л а в и а т у р а . В п о с л е д о в а т е л ь н о м х • йстве очередной с и м в о л м о ж е т б ы т ь п р о ч и т а н т о л ь к о п о с л е г г а предыдущего символа. Д л я т а к и х у с т р о й с т в о п е р а ц и о н н а я ® тема формирует запрос, к о т о р ы й п о с ы л а е т с я н е п о с р е д с т в е н н о Ливеру внешнего устройства.
Параллельными (блочными) устройствами н а з ы в а ю т с я r a ti». для которых обмен информацией в ы п о л н я е т с я б о л ь ш и м и |кани. К таким устройствам относятся д и с к и . Обычно обмен 259
б л о к а м и в ы п о л н я е т с я м е ж д у у с т р о й с т в а м и и памятью с помощьк к о н т р о л л е р а п р я м о г о д о с т у п а к п а м я т и (Direct Memory Accest DMA) без у ч а с т и я п р о ц е с с о р а . Д л я б л о ч н ы х устройств очеред1 б л о к д а н н ы х м о ж е т б ы т ь п р о ч и т а н без ч т е н и я предыдущего, з с т а т о ч н о з н а т ь а д р е с б л о к а , к о т о р ы й д о л ж е н б ы т ь прочитан.
7.2. Управление операциями I / О для символьных устройств П р о д о л ж и т е л ь н о с т ь о п е р а ц и и I / O ч а с т о является непрг: с к а з у е м о й . О н а м о ж е т з а в и с е т ь от с л у ч а й н ы х событий (ног п а к е т д а н н ы х д о с т а в л я е т с я по с е т и ) и л и человеческого факте ( к о г д а п о л ь з о в а т е л ь н а ж и м а е т к л а в и ш у на клавиатуре). В лю& к с л у ч а е Д У , к о т о р ы й з а п у с к а е т о п е р а ц и ю I / O , должен управл, с и г н а л а м и з а в е р ш е н и я о п е р а ц и и и л и и с т е ч е н и я тайм-аута : ля I / O . В с л у ч а е з а в е р ш е н и я о п е р а ц и и ДУ ч и т а е т регистр состояння д л я о п р е д е л е н и я у с п е ш н о с т и з а в е р ш е н и я о п е р а ц и и I/O. В слу з а в е р ш е н и я t i m e - o u t , д р а й в е р « з н а е т » , ч т о что-то произошло,• к а к м а к с и м а л ь н ы й и н т е р в а л в р е м е н и п о з в о л я е т операции завет шиться, если ничего не случилось. И с п о л ь з у е т с я 2 способа к о н т р о л я з а в е р ш е н и я операции I называемые методом опроса и методом прерывания. 7.2.1. Метод опроса П р о ц е с с о р п р о в е р я е т ( о п р а ш и в а е т ) р е г и с т р состояння р о й с т в а до т е х п о р , п о к а о п е р а ц и я не з а в е р ш и т с я . Драйвер дп ж е н т а к ж е п р о в е р я т ь в ы х о д п о t i m e - o u t s . Простой пример реет з а ц и и опроса: for(;;)
{ if (устройство завершило работу) break; if (—count == 0) //Время закончилось break;
} П е р е м е н н а я count, к о т о р а я и н и ц и а л и з и р у е т с я перед Ц11 к л о м , у м е н ь ш а е т с я на к а ж д о м ц и к л е и используется для проверк и п о в р е м е н и . Е с л и в р е м я , т р е б у е м о е д л я завершения операц I / O о т н о с и т е л ь н о в е л и к о , н а п р и м е р , п о р я д к а миллисекунд, такая 260
anu становится неэффективной, т а к к а к п р о ц е с с о р п р о с т а и в а е т I задании завершения о п е р а ц и и . 7.2.2. Режим прерывания Прерывание можно использовать т о л ь к о в т о м с л у ч а е , е с л и [Ьсллер устройства способен в ы з ы в а т ь о б р а б о т ч и к п р е р ы в а ем завершении операции I / O . Р а с с м о т р и м этот м е х а н и з м на мере драйвера клавиатуры. К о г д а п о л ь з о в а т е л ь и с п о л ь з у е т у«мшю чтения символа д л я к л а в и а т у р ы , к о м а н д а в в о д а п о с ы ла на управляющий регистр у с т р о й с т в а . П о с л е н е п р е д с к а з у е L интервала устройство п о л о ж и т о д и н б а й т д а н н ы х во в х о д н о й о тгр. Драйвер устройства в о з в р а щ а е т этот б а й т к а к р е з у л ь т а т индии чтения. В этом случае л у ч ш е и с п о л ь з о в а т ь п р е р ы в а н и я , г jx неизвестно, сколько в р е м е н и н е о б х о д и м о ж д а т ь о т в е т а «5гр°йства. Фактически необходимо в ы п о л н и т ь д в е ф у н к ц и и : -чтение символа; - управление п р е р ы в а н и я м и .
Алгоритм функции ч т е н и я с и м в о л а 1 : 1. Проверка эксклюзивности д о с т у п а к к л а в и а т у р е и б л о вэтание использования к л а в и а т у р ы д р у г и м и п р о ц е с с а м и (celt?).
2. Событие (флаг) для п р е р ы в а н и я у с т а н а в л и в а е т с я в с о с т о я w «Занято». 3. Команда чтения с и м в о л а п е р е д а е т с я у с т р о й с т в у .
4. Процесс блокируется до тех п о р , п о к а с о б ы т и е ( ф л а г ) п р е мия не будет установлено в с о с т о я н и е «Свободно», ч т о свиде*ь:[вует о том, что операция ввода с и м в о л а з а в е р ш е н а , с и м в о л 5. По завершении операции ввода с и м в о л а п р о ц е с с р а з б л о к и Г' ivH. Когда диспетчер д а с т к в а н т в р е м е н и д л я п р о ц е с с а , в ы п о л н я •n I вторая часть этой ф у н к ц и и :
- копируется готовый с и м в о л в а д р е с н о е п р о с т р а н с т в о п о л ь • ателя; -освобождается с е м а ф о р .
Алгоритм обработчика п р е р ы в а н и й . 1. Чтение символа из регистра у с т р о й с т в а ( п о р т а ) в б у ф е р д л я •шла. Itir.ритме не рассматривается обработка тайм-аута.
261
2. У с т а н о в к а с о б ы т и я ( ф л а г а ) в с о с т о я н и е «Свободно». 3. В ы з о в д и с п е т ч е р а п р о ц е с с о в д л я разблокирования промк са из очереди.
7.3. Управление операциями I / O для блочных устройств Т и п и ч н ы е б л о ч н ы е у с т р о й с т в а , а н а л о г и ч н ы е жестки к а м , и м е ю т о ч е н ь б о л ь ш о е с р е д н е е в р е м я доступа. Каждая овд»ц и я т р е б у е т н е с к о л ь к о м и л л и с е к у н д д л я з а в е р ш е н и я , так как т б у е т с я в р е м я д л я п е р е м е щ е н и я г о л о в к и д л я достижения позишл. где з а п и с а н ы д а н н ы е . О д н а к о , к о г д а г о л о в к и на месте, данньпередаются значительно быстрее. П о э т о й п р и ч и н е д л я д о с т и ж е н и я достаточной произвол, т е л ь н о с т и д л я ж е с т к и х д и с к о в и а н а л о г и ч н ы х устройств за оц\ о п е р а ц и ю п е р е д а ю т с я н е с к о л ь к о с о с е д н и х байтов за раз. Напп н а е м , ч т о т а к и е у с т р о й с т в а н а з ы в а ю т с я б л о ч н ы м и . Соседние т ы , п е р е д а в а е м ы е з а о д н у о п е р а ц и ю , н а з ы в а ю т с я сектором м е р с е к т о р а д л я б о л ь ш и н с т в а у с т р о й с т в и ф а й л о в ы х систем ра;-н 5 1 2 б а й т . Д и с к и п р е д о с т а в л я ю т в о з м о ж н о с т ь работы с секторам д р у г и х р а з м е р о в ( 2 5 6 , 1 0 2 4 , 2 0 4 8 ) . С е к т о р — это минимальны! р а з м е р , к о т о р ы й м о ж н о п е р е д а т ь з а о д н у операцию. Болыпинс ф а й л о в ы х с и с т е м (ФС) о б е с п е ч и в а ю т в о з м о ж н о с т ь одновременн п е р е д а ч и н е с к о л ь к и х с м е ж н ы х с е к т о р о в . С м е ж н ы е секторы, | т о р ы е о б р а б а т ы в а ю т с я за о д н у о п е р а ц и ю , называются кластере» в ОС W I N D O W S и б л о к о м в L I N U X . В ы п о л н е н и е о п е р а ц и й д л я б л о ч н о г о устройства значите Ml с л о ж н е е , ч е м д л я с и м в о л ь н о г о , п о э т о м у в д а н н о м пособии расси т р е н ы т о л ь к о о б щ и е п р и н ц и п ы п о с т р о е н и я такого ПО и основни структуры данных. Я д р о д л я п о д д е р ж к и б л о ч н ы х у с т р о й с т в должно учитьшя Ф С , и с п о л ь з у е м ы е д л я у п р а в л е н и я д а н н ы м и на дисках. В сваи с б о л ь ш и м м н о г о о б р а з и е м ФС н е к о т о р ы е ОС, в частности UNL и с п о л ь з у ю т в и р т у а л ь н у ю ФС в м е с т о р е а л ь н о й для упрощенв* м о д у л е й у п р а в л е н и я в в о д о м - в ы в о д о м , к о т о р ы е в этом случ! зависят от конкретной ФС. 7.3.1. Хранение данных о драйвере блочного устройств Д р а й в е р ы б л о ч н ы х у с т р о й с т в м о г у т з а г р у ж а т ь с я в продет» з а г р у з к и ОС, а м о г у т з а г р у ж а т ь с я в п р о ц е с с е работы при неог 262
'сти. Если используется второй в а р и а н т , то все з а г р у ж е н н ы е бверы записываются в х е ш - т а б л и ц у . В з т о м с л у ч а е , е с л и недпмо работать с устройством, п р о в е р я е т с я н а л и ч и е д а н н о г о "ства в этой таблице. Е с л и оно в н а л и ч и и , то т р е б у е м ы й | тер уже загружен. Д л я о б е с п е ч е н и я к о р р е к т н о й в ы г р у з к и ,явера он имеет счетчик и с п о л ь з о в а н и я и в ы г р у ж а е т с я , е с л и •ржимое этого счетчика р а в н о 0. Д л я о б е с п е ч е н и я э к с к л ю '•чого доступа используется с е м а ф о р , а н а л о г и ч н о т о м у , к а к шло для символьного у с т р о й с т в а . К р о м е э т о г о , д л я д р а й в е р а ся информация об устройстве, к о т о р о м у с о о т в е т с т в у е т этот
7.3.2. Инициализация драйвера блочного устройства Для драйвера блочного у с т р о й с т в а д о л ж н а б ы т ь о п р е д е л е н а ада функций (методов), к о т о р ы е м о ж е т в ы п о л н я т ь этот д р а й одержащая имена и а д р е с а д а н н ы х ф у н к ц и й . А д р е с э т о й вцы находится в фиксированной п е р е м е н н о й , п о э т о м у в с е г д а во узнать, поддерживается ли з а д а н н а я ф у н к ц и я , и, е с л и д а , щ адрес. Примеры функций драйверов б л о ч н ы х у с т р о й с т в п р и в е д е н ы '/3.6.1. Таблица
6.1
Некоторые функции для б л о ч н ы х у с т р о й с т в ( н а п р и м е р е L I N U X ) г
1 кипя
Выполняемые действия Создание нового ф а й л а и л и о т к р ы т и е с у щ е с т в у ю щ е г о
'•tease
Закрытие файла Позиционирование о т к р ы т о г о ф а й л а
••«J
Чтение из файла т е к у щ е й з а п и с и
Л
Запись в текущее м е с т о ф а й л а
'"зр
Отображение ф а й л а н а п а м я т ь
off,
Выполнение п о л ь з о в а т е л ь с к и х ф у н к ц и й Рассмотрим а л г о р и т м ф у н к ц и о н и р о в а н и я О С п р и з а п р о с е н а
• " ' Л к устройству.
1. Проверяет, инициализировано ли у ж е у с т р о й с т в о ( т . е . б ы л • «доступ к этому устройству). Е с л и у с т р о й с т в о у ж е и с п о л ь м . :ь, счетчик его использования у в е л и ч и в а е т с я на 1. Р а б о т а •пиши завершена. 263
2- И щ е т д р а й в е р б л о ч н о г о у с т р о й с т в а в хеш-таблице. • »» д р а й в е р н е н а й д е н ( с о о т в е т с т в у ю щ и й д р а й в е р н е загружен), f l p t i в е р з а г р у ж а е т с я , в х е ш - т а б л и ц у д о б а в л я е т с я н о в ы й элемент 3. З а п и с ы в а е т а д р е с с т р о к и х е ш - т а б л и ц ы в п о л е дескриптор! j д л я э т о г о у с т р о й с т в а в с п и с к е д е с к р и п т о р о в устройств в ядр*С 4. С о з д а е т с я д е с к р и п т о р в п о л е д е с к р и п т о р о в устройств- В воле д е с к р и п т о р а з а п и с ы в а е т с я и н ф о р м а ц и я об устройстве, и т числе размер сектора, блока.... Р а с с м о т р и м а л г о р и т м ф у н к ц и о н и р о в а н и я ОС при запро доступ к устройству с помощью о п е р а ц и и Open.
•
1 . П р о в е р я е т с я п о л е д е с к р и п т о р а д л я устройства ( в сига» д е с к р и п т о р о в п р о ц е с с а ) , н а к о т о р о м н а х о д и т с я заданны* ф»Г. Е с л и э т о т д е с к р и п т о р р а в е н О , т о в ы п о л н я т с я предыдущая фуи. ц и я ( ф у н к ц и о н и р о в а н и я ОС п р и з а п р о с е на доступ к устройся 2 . Д л я з а д а н н о г о д е с к р и п т о р а о п р е д е л я е т с я адрес n»4JLi. j т а б л и ц ы ф у н к ц и й и ф у н к ц и и O p e n в э т о й т а б л и ц е . Если пдр»*- at ч а л а т а б л и ц ы ф у н к ц и й и л и а д р е с ф у н к ц и и р а в е н О , т о проимш> ошибка. 3 . У в е л и ч и в е е т с ч е т ч и к и с п о л ь з о в а н и я д л я данного yrrpJ ства. 4 . З а п у с к а е т с я о п е р а ц и я Open. 7.3.3. Б у ф е р ы Д л я в ы п о л н е н и я о п е р а ц и й в в о д а - в ы в о д а я д р о вылг т и б у ф е р , к о т о р ы й и с п о л ь з у е т о б л а с т ь о п е р а т и в н о й памяти идя р а з м е р б у ф е р а р а в е н р а з м е р у б л о к а ( к л а с т е р а ) . Когда zipaiaq у с т р о й с т в а ч и т а е т б л о к с д и с к а , о н з а п о л н я е т ссответсти» щ и й буфер з н а ч е н и я м и » п о л у ч е н н ы м и о т устройства: д о й ! т о м у , к а к д р а й в е р п и ш е т б л о к н а д и с к , о н обновляет г о о п г с т в у ю щ у ю г р у п п у б а й т о в н а у с т р о й с т в е с п о м о щ ь ю обвоа н и я с о о т в е т с т в у ю щ е г о б у ф е р а . Я д р о О С х р а н и т список буферо» в к о т о р о м к а ж д ы й э л е м е н т с о д е р ж и т а д р е с буфера, c c t M i т с л е д у ю щ и й б у ф е р и с с ы л к у на м е с т о д и с к а , с которого прочат» н ы и л и д о л ж н ы б ы т ь з а п и с а н ы д а н н ы е и з б у ф е р а . Так гак i ч е с т в о б у ф е р о в , к а к п р а в и л о , м е н ь ш е , ч е м количество запросе н а в в о д - в ы в о д д а н н ы х , т о п р и х о д и т с я о с в о б о ж д а т ь буферы i * о ч е р е д н ы х о п е р а ц и й . Д л я о с в о б о ж д е н и я б у ф е р о в применяете с л е д у ю щ е е п р а в и л о : о с в о б о ж д а е т с я б у ф е р , к о т о р ы й н е нспоа з о в а л с я д о л ь ш е в с е х . В с п и с к е д л я к а ж д о г о б у ф е р а О С хранл т а к ж е ф л а ж о к д о с т о в е р н о с т и б у ф е р а , в р а м я , чераз которое r% \ 264
ДОнмое буфера гарантированно д о л ж н о быть сброшено на д и с к вручав операции записи, п р и з н а к и з м е н е н и я д а н н ы х в буфере ^Иаые обновились и должны быть повторно с б р о ш е н ы на д и с к ) . 7.3.4. Введение в а р х и т е к т у р у д р а й в е р а для блочных устройств
Так как установка позиции на д и с к е д л я б л о к а требует мноВ^емени, ядро ОС пытается у п о р я д о ч и т ь з а п р о с ы на о п е р а ц и и том образом, чтобы минимизировать к о л и ч е с т в о п е р е м е щ е н и й . Рв:щ текущий запрос не в ы п о л н я е т с я до очередного запроI Из нескольких запросов, п о д л е ж а щ и х обработке д р а й в е р о м , •выбирает для очередного в ы п о л н е н и я тот, к о т о р ы й приведет Ипшимальному перемещению. Т а к к а к д и с к и обычно с о д е р ж а т •вдовательные файлы, этот простой м е х а н и з м очень э ф ф е к яиый. V Откладывание запросов у с л о ж н я е т у п р а в л е н и е б л о ч н ы м 'Чувством. Действительно, б л о к и р о в а т ь д р а й в е р у с т р о й с т в а мьзя, так как в этом случае д о л ж н ы б ы т ь з а б л о к и р о в а н ы все Чв?рсы, которые обращаются к д а н н о м у д р а й в е р у , п о э т о м у "Годней запрос просто к драйверу не п р и д е т . Д л я того, чтобы ^Санировать драйвер устройства, к а ж д а я о п е р а ц и я I / O обращается асинхронно. Т.е. он не ж д е т п е р е д а ч и д а н н ы х до кон> Высокоуровневый драйвер создает н о в ы й запрос к б л о ч н о м у Пройму или подсоединяет его к у ж е с у щ е с т в у ю щ е м у запросу ° завершается. Низкоуровневый д р а й в е р , к о т о р ы й а к т и Иртется позже, вызывает ф у н к ц и ю д л я п е р е у п о р я д о ч и в а н и я Чгдов, берущую запрос из очереди и у д о в л е т в о р я у щ у ю его, Ьмьзуя необходимые к о м а н д ы д л я д и с к о в о г о к о н т р о л л е р а . Ьёоперация I/O завершена, контроллер д и с к а в о з б у ж д а е т прермание. н соответствующий обработчик в ы з ы в а е т ф у н к ц и ю д л я •йора очередного запроса, если необходима обработка другого из очереди. | Каждый драйвер блочного устройства имеет свою собствен№ очередь запросов; если в очереди более одного запроса, то они «ЦТ бьпь упорядочены так, чтобы у в е л и ч и т ь п р о и з в о д и т е л ь Ьпь за счет минимизации п е р е м е щ е н и я г о л о в к и . Т а к о е упоЩкивание возможно, так к а к запрос с о д е р ж и т и н ф о р м а ц и ю >«ере начального сектора и о к о л и ч е с т в е секторов, к о т о р ы е Ярэбработать. Ниже рассмотрены логические структуры внешних устройств (рккйы и винчестера) без учета файловой с и с т е м ы . 265
7.3.5. Л о г и ч е с к а я с т р у к т у р а д и с к е т ы С о в р е м е н н ы е д и с к е т ы 2 - с т о р о н н и е . О д н а сторона инеет i » м е р 0. в т о р а я 1 . К а ж д а я с т о р о н а п р е д с т а в л я е т собой нвбор . ц е н т р и ч е с к и х о к р у ж н о с т е й ( д о р о ж е к ) . Д о р о ж к и пронумеровав», н а ч и н а я с 0 - Н о м е р 0 п р и с в о е н в н е ш н е й о к р у ж н о с т и . Магскхалн ы й н о м е р с о о т в е т с т в у е т с о м о й в н у т р е н н е й окружности- Такп о б р а з о м , е с л и н а д и с к е т е 8 0 д о р о ж е к , т о и х н о м е р а 0..79. K a i u u д о р о ж к а д е л и т с я н а ч а с т и р е п н о й д л и н ы ( с е к т о р ы ) . Секторы ир» н у м е р о в а н ы , н а ч и н а я с н о м е р а 1. Е с л и на д о р о ж к е 18 сектор», т о и х н о м е р а 1 . . 1 В . Д л я т о г о , ч т о б ы у ч е с т ь и н е р ц и о н и ы е сво1 н д и с к о в о д а , м е ж д у с е к т о р а м и н а х о д я т с я п р о м е ж у т к и . Увельпряп п р о м е ж у т к о в п р и в о д и т к у в е л и ч е н и ю о б л а с т и диска, не на > з у е м о й д л я д а н н ы х . П о э т о м у д л я у м е н ь ш е н и я времени дое—п к п о с л е д о в а т е л ь н ы м с е к т о р а м д о р о ж к н о н и могу т нумеровать J не п о с л е д о в а т е л ь н о , в с з а д а н н ы м ш а г о м , например. 1. 3 . 5 .1 4 Ш а г в ы б и р а е т с я т а к и м о б р а з о м , ч т о б ы под головкой в кажд ы й о ч е р е д н о й м о м е н т в р е м е н и н а х о д и л с я с е к т о р с о следую щ и н о м е р о м . Э т о т ш а г з а в и с и т о т с к о р о с т и в р а щ е н и я дпскв. Е д и н и ц а д о с т у п а к д и с к у — с е к т о р . Ф и з и ч е с к и й адрес шт о р а о п р е д е л я е т с я т р е м я ч и с л а м и ( с т о р о н а — ft, дорожка - t с е к т о р — в). С у ч е т о м ф и з и ч е с к и х р а з м е р о в современных а и с т в с е т р и к о м п о н е н т а н е п р е в о с х о д я т 2 5 5 , п о э т о м у под них о т » д и т с я п о 1 б а й т у , т . е . п о л н ы й ф и з и ч е с к и й а д р е с задается 3 З Д т а м и . Д л я у п р о щ е н и я д о с т у п а к с е к т о р а м д и с к а О С исналыум в м е с т о ф и з и ч е с к о г о л о г и ч е с к и й а д р е с с е к т о р а , т . е . его номер ш д и с к е т е . С е к т о р ы н у м е р у ю т с я в т а к о м п о р я д к е » Секторы нулем! дорожкн нулевой стороны нумеруются в порядке 0,1,.. -1 не 5 - к о л и ч е с т в о с е к т о р о в на д о р о ж к е . С е к т о р ы нулевок дорокха п е р в о й с т о р о н ы н у м е р у ю т с я в п о р я д к е S.S+ 1 . - 2 * 5 - 1 Д ы я н у м е р у ю т с я с е к т о р ы п е р в о й д о р о ж к н н у л е в о й и первой старой с о о т в е т с т в е н н о . М а к с и м а л ь н ы й н о м е р с е к т о р а находится и сам о й в н у т р е н н е й д о р о ж к е п е р в о й с т о р о н ы и и м е е т номер 2 * Г 2 г д е Т — ч и с л о д о р о ж е к на о д н о й с т о р о н е . Т а к , д л н д и с к е т ы р а з м е р о м 1 . 4 4 М б а й т п а р а м е т р ы двсжепе Т - 8 0 , »S = 1 8 , р а з м е р с е к т о р а 5 1 2 б а й т , в э т о м случае объем ш к е т ы р а в е н T*S * 2 * 5 1 2 = 80 * 18 * 2 " 5 1 2 = 80 4 18 л (2 * 5 = 1440 Кбайт = 1.44 Мбайт. К о н т р о л л е р д и с к а и н и з к о у р о в н е в ы й д р а й в е р нсполнупг д л я д о с т у п а к д и с к у ф и з и ч е с к и й а д р е с . О С и промежуточна д р а й в е р ы — л о г и ч е с к и й а д р е с , а п р о г р а м м ы , к а к правило. . — тают с фяйлами. 266
Выведем формулы д л я ф о р м и р о в а н и я л о г и ч е с к о г о а д р е с а по ескому адресу, и наоборот, ф и з и ч е с к о г о а д р е с а — по л о г и ому. Пусть дискета 2-сторонняя, на с т о р о н е Т д о р о ж е к , на д о р о ж f -S секторов. Дан физических! адрес, к о т о р ы й з а д а е т с я т р е м я ч и с л а м и is), где: ( - номер дорожки, н а ч и н а я с 0; h - номер стороны, н а ч и н а я с 0; .< - номер сектора, н а ч и н а я с 1. Определить логический адрес LogAddress. Число секторов на двух с т о р о н а х на п о л н ы х д о р о ж к а х t * I'S; Число секторов на неполной д о р о ж к е h* S + s. Логический адрес ( н у м е р а ц и я с е к т о р о в н а ч и н а е т с я с 0): LogAddress = f * 2* S + h* S+ s -
1.
Пример 1. Определить л о г и ч е с к и й адрес с е к т о р а с ф и з и ч е х:» адресом fc = l , f = l , s = l . Д и с к е т а р а з м е р о м 1 . 4 4 М б а й т . LogAddress = t * 2 * S +
h * S + s - l
=
l * 2 * 1 8 + l * 1 8 +
1 1 = 54. Пример 2. Определить ф и з и ч е с к и й и л о г и ч е с к и й а д р е с по>дего сектора на дискете. Ф и з и ч е с к и й а д р е с {h = 1, t = 7 9 , s = 8). Логический адрес LogAddress = 79 * 2 * 1 8 + 1 * 1 8 + 1 8 -I 2879. Дан логический адрес LogAddress. О п р е д е л и т ь ф и з и ч е с к и й ^•.соответствующий данному л о г и ч е с к о м у . (LogAddress)/(2 h=((LogAddress)%(2
*
S);
* S))/S;
i=((LogAddress)% (2 * S ) ) % S +
1.
Проверим правильность ф о р м у л д л я в ы ч и с л е н и я ф и з и ч е с к о адреса по LogAddress = 54 и 2879. Для LogAddress = 54 получим: I = (LogAddress ) / ( 2 * S) = 54 / 36 = 1; h=((LogAddress)%(2
* S))/S =
54
%
36
-((LogAddress)% (2 * S ) ) % S + 1 = 54 %
/18
=
36 %
1; 18 + 1 = 1.
Логический адрес LogAddress = 54 с о о т в е т с т в у е т ф и з и ч е с к о • /1 = 1,1 = 1, s = l } . I - (LogAddress )/(2 * S) = ( 2 8 7 9 ) / (2 * 18) = 79; h-((LogAddress)%(2 * S))/S = ( 2 8 7 9 % 3 6 ) / 18 = 1; s - ( ( L o g A d d r e s s ) % ( 2 * S ) ) % S + 1 = ( 2 8 7 9 % 3 6 ) % 18 + 1 = 1 8 . 267
Л о г и ч е с к и й а д р е с LogAddress — с к о м у {л = 1 . 1 = 7 9 . s = 18}.
2879 соответствует фиг»
|
7.3.6. П р о г р а м м н ы й д о с т у п к с е к т о р а м дискеты В с о в р е м е н н ы х О С у с т р о й с т в о м о ж н о рассматривать ш ф а й л . В э т о м с л у ч а е н о м е р с е к т о р а ( л о г и ч е с к и й адрес секта»*I» е г о р а з м е р о п р е д е л я ю т с м е щ е н и е в ф а й л е относительно ег • ч а л а . Н и ж е п р е д с т а в л е н а ф у н к ц и я ч т е н и я с е к т о р а дискеты г • д а н н ы м ф и з и ч е с к и м а д р е с о м с п о м о щ ь ю ф у н к ц и й WirtApi. Д е т » ! к с е к т о р а м д и с к е т ы в ОС U N I X а н а л о г и ч е н . BOOL ReadSector (ml Drive, int Head, int Track, int Sector, void Ы] HANDLE hDevice. DWORD ten = 512: hDevice = Creafeft/ef llll.lla:". GENERICREAD \ GENERiC_WRlTE. FILE_SHARE READ | FILE_SHARE_WRITE. NULL. OPENEXISTING. FIL E_FLAG WRITE „THROUGH. NULL}; If (hDevice == INVALID_ HANDLE_VALUE) return FALSE: DWORD SectorNvmber = Track " 16 * 2* Head" IB • Sector- < DWORD Offset - SectorNumber ' 512: Offset = SelFilePointerfhDevice. Offset. NULL. FlLE_BEGh ReedFile (hDevice, buf. 512. &len. 0). CloseHandle (hDevice): return true;
} 7.3.7. Л о г и ч е с к а я с т р у к т у р а в и н ч е с т е р а В и н ч е с т е р , в о т л и ч и е от д и с к е т ы , с о д е р ж и т больше двух i р о н . Д о р о ж к п с о д и н а к о в ы м и о м е р о м н а в с е х сторонах ивэымш цилнндром. Н а п о м и н а е м , ч т о ф и з и ч е с к и й а д р е с н а д и с к е т е aaflaerotij» м я б а й т а м и . Д л я о б е с п е ч е н и я с о в м е с т и м о с т и д и с к е т ы и ввнчеете р а д л я ф и з и ч е с к о г о а д р е с а в а в и н ч е с т е р е т о ж е отводится три Ы т а . Д л я н о м е р а д о р о ж к и и с е к т о р а о т в о д и т с я д в а байта, распав ж е н н ы х н е п о с р е д с т в е н н о д р у г в а д р у г о м . Т е к к а к номер дорожи ( ц и л и н д р а ) п р е в о с х о д и т 2 5 6 . т о д л я э т о г о н о м е р а отводите* • 8 б и т ( к а к д л я д и с к е т ы ) , и 10 б и т . В э т о м с л у ч а е мяксныальет к о л и ч е с т в о ц и л и н д р о в р а в н о 1 0 2 4 - О с т а л ь н ы е 6 б и т отводятся м и н о м е р а с е к т о р п , в э т о м с л у ч а е м а к с и м а л ь н ы й н о м е р секторе U С т р у к т у р а д в у х б а й т о в о г о п о л я с н о м е р о м сектора и дорожал 268
j
0..5 младшего байта о т в о д я т с я д л я н о м е р а с е к т о р а . Б ы 0..7 старшего байта отводятся д л я м л а д ш е й ч а с т и ноцилиндра. БЕТЫ 6 . . 7 младшего байта о т в о д я т с я д л я с т а р ш е й ч а с т и ноцшшндра. Пример. Определить з н а ч е н и я н о м е р а ц и л и н д р а и н о м е р а рапо 2-байтовому значению номера с е к т о р а и д о р о ж к и .
БЕТЫ
unsigned short usCylSec; unsigned uSector = usCylSec & 0x2F; unsigneduCyl = (usCylSec »
8)\
((usCylSec »
6)
«
8);
Вопрос. Зачем использовать т а к о е с л о ж н о е о п р е д е л е н и е циа, почему не использовать д л я его н о м е р а просто с т а р ш и е двухбайтового поля? Ответ. Для доступа к дискете и винчестеру и с п о л ь з о в а л и с ь от я те же функции BIOS (функции п р е р ы в а н и я 13h). Д л я м а эначений номеров дорожек получаем адрес, п р е д с т а в л я е м ы й юво для дискет и винчестера. Определим максимальный объем д и с к а с учетом м а к с и м а л ь 'Вачений компонентов физического адреса: У диска = 28 * 2 10 * (2 6 — 1) * 512 « 224 * 29 = 8 Гбайт. Очевидно, что данный размер не соответствует ф и з и ч е с к о гпмеру современных винчестеров. Д л я обеспечения р а б о т ы ними дисками используют: -логическое разделение диска на о т д е л ь н ы е р а з д е л ы ; -специальные способы адресации секторов д и с к а . 73.8. Логическое р а з д е л е н и е д и с к а на о т д е л ь н ы е разделы
Каждый раздел диска рассматривается к а к л о г и ч е с к и й д и с к , случае каждый раздел может и м е т ь п р е д е л ь н ы й р а з м е р . Первый сектор диска MasterBootRecord с о д е р ж и т : - программу начальной з а г р у з к и ; - таблицу разделов. Программа начальной загрузки
Авализирует правильность т а б л и ц ы р а з д е л о в , о п р е д е л я е т на винчестере, с которого в ы п о л н я е т с я з а г р у з к а ( а к т и в ьаздеч), и передает управление з а г р у з о ч н о м у р а з д е л у . 269
Таблица разделов С о д е р ж и т т а б л и ц у , с о с т о я щ у ю из 4 строк. Каждая строи-» ответствует одвому разделу и з а н и м а е т 16 байт Структура строки таблицы разделов: Struct TABLE{ BYTE Active: BYTE BegHead: WORD BegCylSector; BYTE Systemld; BYTE EndHead: WORD EndCylSector, DWORD RelativeSectors: DWORD Tola/Sectors;
): В э т о й с т р у к т у р е п о л е Active з а д а е т а к т и в н ы й раздел { 1 н е а к т и в н о г о и 0 x 8 0 д л я а к т и в н о г о р а з д е л а ) . Т о л ь к о одни р , д о л ж е н б ы т ь а к т и в н ы м , э т о п р о в е р я е т п р о г р а м м а начальна! я г р у з к и . П о л я BegHead и BegCylSector о п р е д е л я ю т ЯВЧЁЛИЫ! а д р е с р а з д е л а , а п о л я EndHead. EndCylSector — конечный и р т р а з д е л о . П о л е RelativeSectors — л о г и ч е с к и й а д р е с начала р м м а п о л е ТоГз/Secfors — о б щ е е к о л и ч е с т в о с е к т о р о в нп дискете. П Systemld о п р е д е л я е т ф а й л о в у ю с и с т е м у д л я р а з д е л а . Д л я п е р в ы х в и н ч е с т е р о в с л о г и ч е с к и м и разделами н о » | б ы л о с о з д а т ь д о 4 р а з д е л о в п о к о л и ч е с т в у с т р о к таблицы 1 1 с о в р е м е н н ы х в и н ч е с т е р о в о б ы ч н о и с п о л ь з у е т с я только 2 строп т а б л и ц ы д л я л ю б о г о ч и с л а л о г и ч е с к и х р а з д е л о в . Н а каждом • • о с т а в ш а я с я ч а с т ь д и с к а д е л и т с я н а о с н о в н о й раздел и расшкрея н ы й . Н а п р и м е р , е с л и н е о б х о д и м о с о з д а т ь р а з д е л ы С.. D . Е . 1 6: ( в с е г о 5 р а з д е л о в ) , то с к а ч а л а с о з д а е т с я 2 раздела. Обычюй (С:) и р а с ш и р е н н ы й . Н о с л е д у ю щ е м ш а г е р а с ш и р е н н ы й д е л и т с я на 2 р а з д е л а . О б ы ч н ы й (£);) и р а с ш и р е н н ы й - Далее ю т с я 2 р а з д а л а ( Е : и р а с ш и р е н н ы й ) . Д а л е е (F. и расширена; ) | н а к о н е ц . С:. К а ж д ы й р а с ш и р е н н ы й р а з д е л н а ч и н а е т с я с сектор с т р у к т у р а к о т о р о г о т а к а я ж е , к а к MasterBootRecord* только т д е р ж и т з а г р у з о ч н о й п р о г р а м м ы . Т а к и м о б р а з о м , можно соашт л ю б о е ч и с л о р а з д е л о в нп в и н ч е с т е р е , но к а ж д о м у разделу про | ш е с т в у е т с е к т о р с и н ф о р м а ц и е й об э т о м и последующем paras ренном разделе. Структура первого сектора раздела. struct MBR{ BYTE Load[0x1be): 270
TABLE t[4]; WORD Sig; ]•
Поле Sig (подписи) содержит б а й т ы 0 x 5 5 A A . Заметим, что проблему а д р е с а ц и и д а н н ы х на д и с к е и с п о л ь з о KJ не логических разделов не р е ш а е т п о л н о с т ь ю , т а к к а к в т а б л и разделов необходимо з а д а в а т ь н а ч а л ь н ы й и к о н е ч н ы й адреса Специальные способы а д р е с а ц и и с е к т о р о в д и с к а (Logical Block Addressing — LBA)
Для адресации данных ф и з и ч е с к и й а д р е с не и с п о л ь з у е т с я , •Кяяется только логический адрес, т . е . н о м е р с е к т о р а на дисr-.Такимобразом, в таблице р а з д е л о в и с п о л ь з у ю т с я т о л ь к о п о л я tiveSedors
TotalSectors.
и
Если для логического адреса и с п о л ь з о в а т ь 4 б а й т а , то м а к с и Я2
и
• ьное количество секторов д и с к а 2 и максимальный размер зс. 2 2 * 2 9 = 241, или 2 т е р а б а й т а , ч т о с е г о д н я д о с т а т о ч н о д л я и аия размера винчестера. Тикая схема работы с д и с к о м и с п о л ь з у е т с я т о л ь к о д л я W I N B0WS 2000 с NTFS и FAT32. 73.9. Программный доступ к секторам винчестера В современных ОС винчестер, к а к и д и с к е т у , м о ж н о р а с с м а I тькак файл. Доступ к т а к о м у « ф а й л у » д о п у с к а е т с я т о л ь к о •Климе администратора. В этом с л у ч а е н о м е р с е к т о р а ( л о г и ч е I адрес сектора) и его размер о п р е д е л я ю т с м е щ е н и е в ф а й л е те. ительно его начала. Н и ж е п р е д с т а в л е н ф р а г м е н т п р о г р а м м ы 3* ненпя MBR для первого в и н ч е с т е р а и о п р е д е л е н и я а к т и в н о г о ia на этом винчестере с п о м о щ ь ю ф у н к ц и й WinApi. ircpy(DnveName, " l l l l . i l P h y s i c a l D r i v e O " ) ; HANDLE hDevice
=
CreateFile(DriveName,
//drive
to
GENERIC READ\GENERIC_WRITE, FILE SHARE
open
READ,
NULL OPEN_EXISTING, FILE_ FLAC_ WRI TE_ THROUGH, NULL); i'hDevice == INVALID HANDLE VALUE) throw
HARDDISKERROR();//we
can't
open
the
ULONG count;
BOOL Ь =
ReadFile (hDevice, &Mbr, 512, &count, 0 );
w \\ count 1=512) throw
HARDDISKERRORQ;
inh
b(i-0;i<4;i++)f
271
drive
if
(MbrJ[iJ.Active==0x80){ ActivePart = i; break;
)
) О б р а т и т е в н и м а н и е н а з а д а н и е и м е н и д л я жесткого д«- i д л я первого и л и единственного винчестера!
7.4. Режимы управления вводом-выводом К а к б ы л о с к а з а н о в ы ш е , и м е е т с я 2 р е ж и м а управления п с д о м - в ы в о д о м : р е ж и м о п р о с а и р е ж и м п р е р ы в а н и й . Всоответсп» с р е ж и м о м о п р о с а , а л г о р и т м в в о д а - в ы в о д а и м е е т вил: while (Устройство занято); Установка флага занятости устройства. while (Выполняется запрос), Сброс флага занятости устройства: Р е ж и м о п р о с а о ч е н ь п р о с т о р е а л и з у е т с я , но не IICDOJ Ы « д л я м н о г о з а д а ч н ы х с и с т е м , т а к к а к р а с с ч и т а н н а режим ояищ н и я процессором з а в е р ш е н и я о п е р а ц и и ввода-вывода. Алгоритм обработки прерываний: 1. Формирование запроса ввода-вывода. 2 . З я п у с к о б р а б о т ч и к а п р е р ы в а н и й д л я заданного угтро! ства. 3 . В ы п о л н е н и е н о в о г о п о т о к а и л и п р о д о л ж е н и е еьшот > м текущего. 4 . П р е р ы в а н и е п о в а в е р ш е н и и о п е р а ц и и ввода-вывода 5 . В о з о б н о в л е н и е р а б о т ы п о т о к и , п о с л а в ш е г о запрос л * вывод. Д а н н ы й а л г о р и т м б о л е е с л о ж н ы й , н о д о п у с к а е т возня н о с т ь о д н о в р е м е н н о г о в ы п о л н е н и я н е с к о л ь к и х запросов з а р е е н т е р а б е л ь н о с т и к о д а д л я о б р а б о т ч и к о в п р е р ы в а н и й , в таи» з н а ч и т е л ь н о у м е н ь ш а е т п о т е р и в р е м е н и процессора, связями с з а в е р ш е н и е м о п е р а ц и и в в о д а - в ы в о д а . Е с л и продолжаете» а * п о л н е н и е т е к у щ е г о п о т о к а , г о в о р я т о б а с и н х р о н н о м вводе-пы: де, иначе о синхронном. Д р а й в е р ы , к о т о р ы е р а б о т а ю т в р е ж и м е обработки прерыкНИЙ. с о д е р ж а т н е с к о л ь к о с е к ц и й , с р е д и к о т о р ы х — с е к ш и г а ц и а л и э я ц и и , с е к ц и и о б р а б о т к и п р е р ы в а н и й , с е к ц и и оСрабсм* завершения прерываний. 272
7.5. Абстрактные понятия различий устройств (абстрагирование от различий). Виртуальные внешние устройства Некоторые из внешних устройств д о л ж н ы и с п о л ь з о в а т ь с я ом в монопольном р е ж и м е . Н а п р и м е р , п р и н т е р д о л ж е н "оваться одновременно только о д н и м п р о ц е с с о м , в противгучае трудно будет разделить р е з у л ь т а т ы вывода, относя•Я к разным процессам. Д л я р е ш е н и я этой п р о б л е м ы м о ж н о вать два способа. Первый способ п р е д п о л а г а е т з а к р е п л е истваза процессом вплоть до его о к о н ч а н и я . Д л я предотI взаимной блокировки все процессы, к о т о р ы е требуют работы занятое устройство, не могут с т а р т о в а т ь , а з н а ч и т , окно параллельное выполнение т а к и х процессов. Второй 5 предполагает использование т а к н а з ы в а е м ы х в и р т у а л ь устройств. В этом случае к а ж д о м у процессу в ы д е л я е т с я свое ьвое устройство для ввода-вывода. В ы в о д на п р и н т е р ф а к | заменяется выводом в п а м я т ь и л и ф а й л . Ф а к т и ч е с к и й данных на принтер выполняется с п е ц и а л ь н ы м с и с т е м н ы м юм, который управляет этим выводом с учетом п р и о р и т е "ессов. Такой процесс называется с п у л е р о м . Современные операционные с и с т е м ы о б ы ч н о и с п о л ь з у ю т "способ. 'ртуализация устройств используется т а к ж е д л я обеспенезависимости программ п о л ь з о в а т е л я от к о н к р е т н ы х хустройств. Так, программа не д о л ж н а зависеть от вводаданных на такие различные устройства, к а к с т а н д а р т н о е "во (экран монитора), дискета, ж е с т к и й д и с к с р а з л и ч н о й и системой, CD, USB-устройства и д р . П р о г р а м м и с т задавазываемое логическое и м я устройства (/А:, В:, С:,...). ОС по «кому имени определяет тип соответствующего устройства "ности организации данных на этом устройстве ( ф а й л о в у ю у). Используя драйвер файловой с и с т е м ы , о п р е д е л я е т с я кий адрес на устройстве, к которому необходимо обрагцеИ пользуя физические драйверы д л я устройства з а д а н н о г о выполняется доступ к диску заданного т и п а .
7.6. Стратегии буферизации и кэширования Скорость работы внешних устройств и процессора существенются. Для уменьшения в л и я н и я э т и х р а з л и ч и й испольбуферизация. Рассмотрим и с п о л ь з о в а н и е б у ф е р и з а ц и и 273
п р и в в о д е д а н н ы х . Д а н н ы е ч и т а ю т с я в б у ф е р . Во время испо % з о в а н и я д а н н ы х п р о ц е с с о р о м о ч е р е д н а я п о р ц и я д а н н ы х чнт»« с я в д р у г о й б у ф е р . В э т о м с л у ч а е и с п о л ь з о в а н и е данных о д м » буфера и заполнение другого буфера в ы п о л н я е т с я ппраллдо* Количество т п к и х буферов определяется отношением с к о Щ Я у с т р о й с т в а в в о д а - в ы в о д а и п р о ц е с с о р а . А н а л о г и ч н о использую •« буферы при записи данных. К э ш и р о в а н и е о б е с п е ч и в а е т в о з м о ж н о с т ь использования явн ы х , к о т о р ы е б ы л и п р о ч и т а н ы р а н е е , без и х повторного чтеши. Н а п р и м е р , е с л и с о д е р ж и м о е ф а й л а н а х о д и т с я в буфере и програив в ы д а е т з а п р о с на ч т е н и е э т о г о ф а й л е , он п о в т о р н о не читается, а ип о л ь з у е т с я его с о д е р ж и м о е и з п а м я т и . К р о м е этого, м и в н м а л и и п о р ц и я д а н н ы х , ч и т а е м ы х с д и с к а , о п р е д е л я е т с я размером и, к а к п р а в и л о , р а в н о 5 1 2 б а й т . По з а п р о с у пользователя мог - Я с л е д о в а т е л ь н о ч и т а т ь с я п о р ц и и с м е н ь ш и м р а з м е р о м . В этох CJIJW п е р е д ч т е н и е м о ч е р е д н о й п о р ц и и д а н н ы х с д и с к а сличила проверяйс я , н е б ы л и л я э т и д а н н ы е у ж е п р о ч т е н ы . Е с ч и д а н н ы е уже в паншг повторного обращения к д и с к у не выполняется. Порция прочит н ы х д а н н ы х м о ж е т б ы т ь б о л ь ш е с е к т о р а , н о всегда остается кратяк р а з м е р у с е к т о р а . Ч е м б о л ь ш е р а з м е р п о р ц и и , т е м в ы ш е верот • того, ч т о д а н н ы е , к о т о р ы е п о т р е б у ю т с я на с л е д у ю щ е м шаге, окая 1 с я в п а м я т и - Д л я у п р а в л е н и я к э ш е м д и с к а используетсясистемы! п р о ц е с с , к о т о р ы й о р г а н и з у е т д о с т у п к д а н н ы м и их чтение : с — н е о б х о д и м о с т и . А н а л о г и ч н о , п р и з а п и с и д а н н ы х они фпкти I я з а п и с ы в а ю т с я в о п е р а т и в н о й п а м я т и и п е р е н о с я т с я на лиск с и п я н ы м п р о ц е с с о м п о д у п р а в л е н и е м ОС- Д л я п р о г р а м м ы считается т г т е к и е д н н н ы е у ж е н а х о д я т с я н а д и с к е . П о з а п р о с у пользователя ш н ы е м о г у т б ы т ь п р и и у д и т е л ь н о з а п и с а н ы на д и с к . Обычно ОС < а ется» к а к м о ж н о д о л ь ш е не з а п и с ы в а т ь д а н н ы е на д и с к . Это n w • е т в ы п о л н и т ь о д н у о п е р а ц и ю з а п и с и п р и м н о г о к р а т н о м изменив э т и х д а н н ы х . Сброс на д и с к в ы п о л н я е т с я в том случае, если буфчь т р е б у ю т с я д л я з а п и с и д р у г и х д а н н ы х . Д л я у в е л и ч е н и я надежи.*» з а п и с и д а н н ы е ж е л а т е л ь н о с б р о с и т ь нп д и с к к а к м о ж н о быстрее, m к а к в с л у ч а е о т к л ю ч е н и я э л е к т р о э н е р г и и о н и будут потеряны. Рассмотрим п р о б л е м ы п о и с к а требуемых данных на дн
7.7. П р я м о й д о с т у п к п а м я т и 7.7.1. П р я м о й д о с т у п к п а м я т и ( D M A ) С о в р е м е н н ы е в ы ч и с л и т е л ь н ы е с и с т е м ы в к л ю ч а ю т лог •« н и т е л ь н ы й п р о ц е с с о р D i r e c t M e m o r y А с с е в з C o n t r o l l e r (D.MAC1 274
и^рый может использоваться д л я п е р е д а ч и д а н н ы х м е ж д у №! и устройством I/O. Будучи а к т и в и з и р о в а н н ы м CPU, DMAC ркет продолжить передачу данных сам; когда передача д а н н ы х шается, DMAC посылает запрос на п р е р ы в а н и е . К о н ф л и к т тся, если CPU и DMAC необходим доступ к одной и той же ги памяти одновременно, он р а з р е ш а е т с я а п п а р а т н ы м преем. DMAC используется драйверами блочных устройств, как время запуска DMAC относительно велико, д л я передачи лыпого числа байтов более эффективно использовать CPU. При использовании DMAC необходимо п о м н и т ь , что этот -•"юллер работает с адресами ш и н ы , а не с адресами оперативна ламяти и портами. Адреса ш и н ы используют все устройства, ttffleCPU, для управления ш и н о й д а н н ы х . В Р С - а р х и т е к т у р е Вуа шины совпадают с физическими адресами; однако в дру• архитектурах (подобно S u n ' s S P A R C и H e w l e t t - P a c k a r d ' s 1а), эти два вида адресов отличаются. Т а к к а к в о п е р а ц и я х Ш передача данных выполняется без у ч а с т и я CPU, ш и н а дан•ишравляется напрямую устройством I / O и DMAC. Поэтому, ядро запускает DMA-операцию, в ней д о л ж н ы быть у к а з а н ы "а шины. Если эти адреса не совпадают с адресами оператив ь памяти, ОС должна содержать ф у н к ц и и д л я преобразования Ф>т
При выполнении операций DMAC в з а и м о д е й с т в у е т с P I C я роллером прерываний), который используется д л я управ« на внешними устройствами. Операции прямого доступа к паurn юответствует вектор прерываний, к о т о р ы й н а з н а ч а е т с я п р и Шгализации операции. Этот вектор используется д л я сигналичии о завершении операции передачи д а н н ы х . Чтобы начать операцию DMA, драйвер устройства у к а з ы в а е т ipr буфера шины DMA, направление передачи, р а з м е р д а н н ы х устройства I/O; затем драйвер приостанавливает т е к у щ и й с. Когда DMA передает сигнал о к о н ц е операции, устройвозбуждает прерывание, к о т о р о е о б р а б а т ы в а е т д р а й в е р "ства.
7.8. Вопросы и задачи 1. В чем отличие символьных устройств от б л о ч н ы х ? П р и в е д и т е примеры устройств каждого типа. 2. Какие методы управления у с т р о й с т в а м и и с п о л ь з у ю т с я д л я символьных устройств? Поясните э т и м е т о д ы на п р и м е р е к л а в и а т у ры или мыши.
275
3. С м о д е л и р у й т е у п р а в л е н и е к л а в и а т у р о й в режиме опроса с помощью стандартных ф у н к ц и й я з ы к а С++: kbhit (), getch (), putch j 4. Что такое сектор, кластер д л я диска? 5. Что такое драйвер? Какие функции драйверов блочных устроМя вы знаете? 6. Какова роль б у ф е р а п р и работе с в н е ш н и м и устройствами? 7. Из к а к и х разделов с о с т о и т д и с к е т а , е с л и д л я нее испольэ\тх* ф а й л о в а я с и с т е м а РАТ12? 8. Составьте п р о г р а м м у д л я ч т е н и я р а з д е л о в дискеты. 9 . И з к а к и х разделов состоит ж е с т к и й диск? 10. Что такое L B A , что будет, е с л и в ы к л ю ч и т ь поддержку этого режима? 11. К а к у ю и н ф о р м а ц и ю с о д е р ж и т M B R ? 12. Составьте п р о г р а м м у д л я ч т е н и я M B R 1 и определения чи« * разделов и ф а й л о в ы х систем д л я ж е с т к о г о диска. 13. Что д а е т р е ж и м п р я м о г о д о с т у п а к п а м я т и при работе с блочным и устройствами?
1 Будьте осторожны при выполнении операций прямого доступа к жесткому лиг ку! Эти операции требуют прав администратора.
276
8. ФАЙЛОВЫЕ СИСТЕМЫ
Цели изучения раздела: I Объяснить необходимость файловых систем. 2. Сравнить различные подходы к о р г а н и з а ц и и файлов, указать сильныеи слабые стороны. Объяснить как развитие ПО привело к изменениям приоритетов евопросах проектирования ФС и управления ими.
8.1. Основные понятия Файл — физическое представление и н ф о р м а ц и и о совокуп•я. объектов [9]. Система управления файлами (СУФ), или файловая система — кисть ОС, которая реализует работу с ф а й л а м и . Она отвечает за •паление файлами на всех этапах их жизненного ц и к л а (созда• уничтожение, организацию, чтение, запись, м о д и ф и к а ц и ю , 1 тещение), а также управляет доступом и ресурсами, кото>к .'"пользуются файлами. На самом абстрактном уровне ф а й л >|К№ рассматривать как упорядоченную п о с л е д о в а т е л ь н о с т ь «;|»«итов стандартной длины. Если в качестве т а к и х элементов рмьзовать байт, то в этом случае файл ничем не отличается от "Гчентв виртуальной памяти. Будем называть содержимое файла д а н н ы м и д л я этого ф а й л а . Первая задача СУФ — эффективное использование дисковол "остранства. Самым эффективным я в л я е т с я р а з м е щ е н и е на •atтолько данных для файлов без справочной т а б л и ц ы о месте Шщения отдельных файлов. Но такое и с п о л ь з о в а н и е д и с к а "дет к невозможности хранения на нем множества файлов. I i^Hu быть справочные таблицы, с о д е р ж а щ и е и н ф о р м а ц и ю 277
о м е с т е х р а н е н и я и с в о й с т в а х ф а й л а ( т о л ь к о д л я чтения. •* создания и другие). К р о м е того, ф а й л ы удаляются, их могут увеличиваться и у м е н ь ш а т ь с я . Чтобы не перемещать» н ы е н а д и с к е , ч т о т р е б у е т д о с т а т о ч н о м н о г о в р е м е н и , исподы-?" ф р а г м е н т и р о в а н н ы е ф а й л ы , д л я к о т о р ы х отдельны! . • ф а й л а р а с п о л о ж е н ы н а н е с м е ж н ы х у ч а с т к а х д и с к а . В этоь • » ч а е р е ш а е т с я з а д а ч а у м е н ь ш е н и я о б ъ е м а справочных г.';«ь в у с л о в и я х ф р а г м е н т и р о в а н н ы х ф а й л о в . С п р а в о ч н ы е та( т е * о б я з а т е л ь н о д о л ж н ы о д е р ж а т ь с л е д у ю щ и е д а н н ы е : иденткфа к а т о р ф а й л а ( и м я ) , а д р е с ф а й л а н а д и с к е . Д л я обеспечения н о м о ж н о с т и и с п о л ь з о в а н и я ф р а г м е н т и р о в а н н ы х данных > ш адр&са д а н н ы х на д и с к е п р и в о д и т с я с п и с о к а д р е с о в д л я вс л «- | у ч а с т к о в . Т а к и м о б р а з о м , т а б л и ц а ф а к т и ч е с к и состоит и.' -тп ч а с т е й : с п р а в о ч н и к и с п и с к и . Н а п о м и н а е м , ч т о диск 01» «••»» к б л о ч н о м у у с т р о й с т в у , в к о т о р о м д а н н ы е передаются 1 ( к л а с т е р а м и 1 ) . Ч е м б о л ь ш е р а з м е р к л а с т е р а , тем выше« д о с т у п о к ф а й л у , т е м м е н ь ш е р а з м е р с п и с к а с д а н н ы м и об «Я к а х ф а й л а . Р а з м е р к л а с т е р а о п р е д е л я е т с я файловой систем^ Л * о п е р а ц и и о б р а щ е н и я к д и с к у с в о д я т с я к ч т е в н ю - з а т г . к ЛиЁ С о о т в е т с т в е н н о , д л я э т и х о п е р а ц и й д о л ж е н б ы т ь выделе" • t i с р а з м е р о м , к р а т н ы м р а з м е р у б л о к а . Т а к к а к п р и образ /•»•» г I д и с к у ф а к т и ч е с к и с ч и т ы в а е т с я ( з а п и с ы в а е т с я ) блок, пврез | р е д н ы м о б р а щ е н и е м к д и с к у Ф С п р о в е р я е т отсутствиетреб - <>ы д а н н ы х в п а м я т и . Д а н н ы е м о г у т б ы т ь в п а м я т и , если ока в щ д я т с я в б л о к е , п р о ч и т а н н о м в р е з у л ь т а т е предыдущих оперял ч т е н и я . ЕСЛИ р а з м е р б у ф е р а б о л ь ш е р а з м е р а б л о к а , т о вероятна* ! н а х о ж д е н и я д а н н ы х в п а м я т и у в е л и ч и в а е т с я . Справочные т ' i цы называют метаданными. Вторая задача СУФ у в е л и ч е н и е с к о р о с т и нахождения т» * б у е м о г о ф а й л а в с п р а в о ч н ы х т а б л и ц а х : о р г а н и з а ц и я таблиц л ш о б р а з о м , ч т о б ы о б е с п е ч и т ь м и н и м а л ь н о е в р е м я поиски-Изистя, 1 ч т о н а и б о л е е б ы с т р ы й д о с т у п в п е р е м е н н ы х т а б л и ц а х может&л» д о с т и г н у т п р и и с п о л ь з о в а н и и д р е в о в и д н ы х с т р у к т у р нла и л т а б л и ц [ 1 2 ] . Т а к и е с т р у к т у р ы д л я т а б л и ц в п е р в ы е исполыоаам | ОС U N I X . В н а с т о я щ е е в р е м я в р а з н о й м е р е используют acecojp | м е н н ы е О С . С у щ е с т в у ю щ и е ФС в н а и б о л ь ш е й степени отлита - • составом и организацией метаданных, которые в значишь*? J степени определяют производительность ФС.
' В файловых системах, которые поддерживаются ОС фирмы Microsoft. »•< гтгв термин кюттрр. Я Г ПГТОМЙХ Г \ 1 Х блок. 278
(
Третьязадача СУФ — ускорение доступа к д а н н ы м ф а й л а , решения этой задачи используются с л е д у ю щ и е м е т о д ы : - прямой доступ к памяти;
-сортировка запросов д л я д о с т у п а к з а п и с я м д и с к а с м и н и -
ьяым перемещением головки; -буферы. Прямой доступ к памяти позволяет в ы п о л н я т ь п а р а л л е л ь н о ш чтения-записи д л я д и с к а и к о м а н д ы п р о ц е с с о р а д л я шшения основной программы. П р и м и т и в ы с и н х р о н и з а ц и и ""лягот решить проблему корректного и с п о л ь з о в а н и я д а н н ы х 1»шнего устройства. Известно, что время, необходимое д л я п о з и ц и о н и р о в а н и я р 1кн, пропорционально количеству д о р о ж е к , на к о т о р ы е неводимо ее переместить д л я в ы п о л н е н и я очередного з а п р о с а . (и:»шные внешние устройства и м е ю т к э ш , к у д а м о ж е т б ы т ь «"сано несколько запросов. П р и выборе очередного з а п р о с а на Гонение учитывается текущее п о л о ж е н и е г о л о в к и . Независимо от длины записи, к о т о р а я д о л ж н а б ы т ь п р о ч и ми, с дпска читается один блок, к о т о р ы й п о м е щ а е т с я в буфер. I и буферов несколько, то о д н о в р е м е н н о в п а м я т и х р а н и т с я Вцшмое нескольких блоков. П р и о б р а щ е н и и к очередной заIM файла она не считывается с д и с к а , если у ж е р а с п о л о ж е н а П .-ом из буферов. Чем больше буферов, тем б о л ь ш е в е р о я т н о с т ь и^ждения требуемых данных в п а м я т и . Четвертая задача СУФ — в о с с т а н а в л и в а е м о с т ь с и с т е м ы , й мнения файлов, как правило, требуют и з м е н е н и й в области аяых на диске и в области метаданных. Эти и з м е н е н и я требуют и. "пения множества команд. Если в процессе э т и х и з м е н е н и й Чвиошел сбой в системе до полного з а в е р ш е н и я и з м е н е н и й , w «.стояние данных не будет соответствовать т а б л и ц а м , и це*>иость файловой системы н а р у ш и т с я . Д л я о б е с п е ч е н и я вос- вавлпваемости целостности необходимо с о х р а н я т ь т е к у щ е е югмние диска до завершения очередной о п е р а ц и и и л и прото* тровать все изменения, в ы п о л н я е м ы е в процессе о п е р а ц и и , JK обеспечения возможности возврата в и с х о д н о е состояние п р и Г 'иополучном завершении о п е р а ц и и . ФС, к о т о р ы е осуществим1 протоколирование выполняемых о п е р а ц и й в с п е ц и а л ь н ы х 279 ггьалах, называются журнальными ФС. пдЖрауанрвнаныахдоступа л на ьны обе»»:"Г0 «•швают Пятая файла целостность задача должны СУФ ФС. быть — защищенность определены д ие сФС кке .нему Д ля
р а з л и ч н ы х г р у п п п о л ь з о в а т е л е й . Е с л и Ф С н е д а е т возмож*«Ч определить т а к и е п р а в а , она о т н о с и т с я к н е з а щ и щ е н н ы й ФС Организация файлов Ф а й л ы м о г у т б ы т ь о р г а н и з о в а н ы т а к и м образом, что искав з а д а т ь а д р е с о ч е р е д н о й з а п и с и ф а й л а ( п р я м о й доступ). Taj г * » ганизацню имеют файлы на дисках. Е с л и з п п п с п ф а й л а м о г у т б ы т ь о б р а б о т а н ы т о л ь к о в пора*» и х з а п и с и н а у с т р о й с т в о , т а к и е у с т р о й с т в а и соответстаугчи и м ф а й л ы н а з ы в а ю т с я ф а й л а м и с п о с л е д о в а т е л ь н ы м досгзилв В этом случае т а к ж е г о в о р я т о пос чедователъной оргавю*а» ф а й л а ( п о с л е д о в а т е л ь н ы й ф а й л ) . В н у т р и ф а й л а з а п и с и могут*»» ф и к с и р о в а н н о й и п е р е м е н н о й д л и н ы . З а п и с и переменной д о и * о б ы ч н о и м е ю т с т р у к т у р у < Д л и н а з а п и с и , З а п и с ь > ичи к а ж ш запись з а к а н ч и в а е т с я с п е ц и а л ь н ы м символом, который ncmmn ется в качестве признака конца записи. П р я м о й д о с т у п п р е д п о л а г а е т , ч т о н е о б х о д и м о В&ращмш к з а п и с я м в п р о и з в о л ь н о м п о р я д к е . Е с л и р а з м е р эпписв фис и р о в а н н ы й , п о н о м е р у з а п и с и и е е р а з м е р у л е г к о вычисдч с м е щ е н и е в ф а й л е . Е с л и з а п и с и п е р е м е н н о й д л и н ы п треб) т & п р я м о й д о с т у п к з а п и с я м ф а й л а , о б ы ч н о используется ц а и н д е к с о в , к о т о р а я с о д е р ж и т а д р е с а н а ч а л а д л я всех оашп4 в виде: И д е н т и ф и к а т о р ( П о м е р з а п и с и ) . А д р е с записи в фав л е > . В т а б л и ц е и н д е к с о в к а ж д ы й э л е м е н т и м е е т фиксирован!]» д л и н у . В э т о м с л у ч а е с н а ч а л а н п х о д и м п д р е с з а п и с и , в сотой жмп о л н я е т с я д о с т у п к т р е б у е м о й з а п и с и . Д л я организации в т а б л и ц е и н д е к с о в и с п о л ь з у ю т с я у п о р я д о ч и в а н и е Видемиш т а б л и ц и л и х е ш - т а б л и ц ы [12J. Основное в р е м я в о п е р а ц и и ч т е н и я - з а п и с и файлов о б щ » з а н и м а е т п о з и ц и о н и р о в а н и е г о л о в к и в н у ж н о м месте диска о» д о с т у п а к о ч е р е д н о й з а п п с п . Ч е м д а л ь ш е д р у г о т друга наход»-» с м е ж н ы е з а п и с и , т е м д о л ь ш е в ы п о л н я е т с я о п е р а ц и я позициейр и в в н и я . Н а и б о л е е б ы с т р ы й д о с т у п в ы п о л н я е т с я д л я фаб.п а п и с и к о т о р о г о н а х о д я т с я в п о с л е д о в а т е л ь н ы х б л о к а х днгкп(ф*1« не фрагментирован).
т«6|»
8.1.2. В и р т у а л ь н а я и р е а л ь н а я ф а й л о в а я память В н а с т о я щ е е в р е м я и с п о л ь з у е т с я о ч е н ь м н о г о различаю Ф С д а ж е в п р е д е л а х о д н о й ОС- З а д а ч у и с п о л ь з о в а н и я файдм, з а п и с а н н ы х в р а з л и ч н ы х Ф С , п р и х о д и т с я р е ш а т ь достаточно 280
I lie. Например, при работе в L I N U X ч и т а т ь д и с к е т у , с о з д а н н у ю I'LNDOWS, и наоборот. Д л я о б е с п е ч е н и я с о в м е с т и м о с т и р а з л и ч ал ФС используется в и р т у а л ь н а я ФС (ВФС). П р и н ц и п р а б о т ы • к ' заключается в следующем: н е з а в и с и м о от Ф С , о н а п р е о б р а ее метаданные к формату, п р и н я т о м у д л я в и р т у а л ь н о й ФС, 11 гасывает эти данные в п а м я т и ( о б л а с т и я д р а ) . П р и з а п р о с е на •ШнеЕие операции (например, ч т е н и я и л и з а п и с и ) В Ф С з а п и Mier в таблицу адрес ф у н к ц и и р е а л ь н о й ФС д л я о б р а б о т к и э т о й Bimm и выполняет к о с в е н н ы й в ы з о в э т о й ф у н к ц и и . Т а к и м ' ом, для расширения в и р т у а л ь н о й ФС п р и п о я в л е н и и н о в о й МьвонФС достаточно добавить ф у н к ц и ю ф о р м и р о в а н и я т а б л и л ВФС по таблицам реальной ФС и д о п о л н и т ь т а б л и ц у а д р е с о в Читчиков функциями-обработчиками д л я р е а л ь н о й Ф С .
8.2. Компоненты файловой системы Дтя того, чтобы определить о с н о в н ы е м о д у л и ф а й л о в о й сиНмы, рассмотрим прохождение з а п р о с а п о л ь з о в а т е л я на д о с т у п • т е п файла. Доступ к текущей записи ф а й л а о с у щ е с т в л я е т с я в с л е д у ю порядке: 1. Определяется устройство, на к о т о р о м р а с п о л о ж е н з а д а н '•J!файл. Файл отыскивается по и м е н и в с п р а в о ч н и к е ф а й л о в о й >т*мы (каталоге). Структура с п р а в о ч н и к а и а л г о р и т м п о и с к а жют от файловой системы. П р и о т к р ы т и и ф а й л а с о з д а е т с я ^VKTоперационной системы « Ф а й л » , в к о т о р о м д л я з а д а н н о г о > ц определяется логический адрес его н а ч а л а (№ с е к т о р а ) на к нном устройстве. Алгоритм о п р е д е л е н и я этого а д р е с а т а к ж е лсит от файловой системы. У к а з а т е л ь ф а й л а у с т а н а в л и в а е т с я начало. В дальнейшем д л я д о с т у п а к э т о м у ф а й л у и с п о л ь з у «м указатель па объект «Файл» ( д е с к р и п т о р ф а й л а ) . 2. По операции чтения с ф а й л а д о л ж н о б ы т ь п р о ч и т а н о задоэе число байтов. По количеству б а й т о в , к о т о р ы е н е о б х о д и м о в»читать, и с учетом физических р а з м е р о в к л а с т е р а о п р е д е л я е т чвело кластеров, которые д о л ж н ы б ы т ь п р о ч и т а н ы . Д л я э т о й в; алии необходимо знать ф и з и ч е с к и е х а р а к т е р и с т и к и в н е ш н е тгтройства. 3. Проверяется, не находятся ли т р е б у е м ы е д а н н ы е в п а м я . Это возможно, так к а к р а з м е р к л а с т е р а м о ж е т п р е в о с х о д и т ь •дер записи, и одна операция ч т е н и я ч и т а е т с р а з у н е с к о л ь к о 281
з а п и с е й . Е с л и д а н н ы е у ж е в п а м я т и , обращение к фи <* устройству д л я ч т е н и я не выполняется. 4. Е с л и т р е б у е м ы е д а н н ы е в п а м я т и отсутствуют, 1ВВЩЦ м о с т и от ч и с л а к л а с т е р о в , к о т о р ы е д о л ж н ы быть прочитям, * м о г у т б ы т ь р а с п о л о ж е н ы в п о с л е д о в а т е л ь н ы х кластерах в • с л е д о в а т е л ь н ы х , е с л и ф а й л ф р а г м е н т и р о в а н . Определен* щ ц и и о ч е р е д н о г о к л а с т е р а з а в и с и т от особенностей задание к л а с т е р о в д л я ф а й л а . В ы п о л н я ю т с я операции чтения дишящ требуемых кластеров. Т а к и м о б р а з о м , н е з а в и с и м о о т используемой ф в и и стемы м о ж н о в ы д е л и т ь с л е д у ю щ и е модули: • и н т е р ф е й с п о л ь з о в а т е л я — ф у н к ц и и , испольс-.-пш*^ доступа к файлу. Н а п р и м е р , в стандартном 0 - + и с п о л н и м д у ю щ и е ф у н к ц и и : fopen, fclose, fread, fwrite и т.д. Этн фу:иш( з а в и с я т от ф и з и ч е с к и х у с т р о й с т в , на которых pacno.ic;t л ы . В к а ч е с т в е с и с т е м н ы х в ы з о в о в ОС U N I X используют* ф,,м ц и и open, close, read, write. В к а ч е с т в е системных вызове*! D O W S и с п о л ь з у ю т с я CreateFile, CloseHandle, ReadFile, ИМ • п р о ц е д у р ы д о с т у п а , в к л ю ч а ю щ и е в себя поиск и а в о ч н и к у , с о з д а н и е о б ъ е к т о в о п е р а ц и о н н о й системы, осрадяя л о г и ч е с к о г о и ф и з и ч е с к о г о а д р е с о в н а ч а л а файла, узри буферами; • с и с т е м ы в в о д а - в ы в о д а , п о д д е р ж и в а ю щ и е очередь J«I на в в о д - в ы в о д , п л а н и р о в а н и е о п е р а ц и й ввода-вывода д > с п е ч е н и я м а к с и м а л ь н о й п р о и з в о д и т е л ь н о с т и за счет уши; п е р е м е щ е н и я г о л о в о к , о б р а б о т к у о ш и б о к и завершение о о . а раций; • и с п о л ь з о в а н и е в с п о м о г а т е л ь н о й памяти (кэша), к<<,*| все д а н н ы е с р а з у з а п и с ы в а ю т с я на д и с к ; возможно, что в мЯ н ы х операциях эти данные будут изменены; • в о с с т а н о в л е н и е п р и с б о я х , обеспечивающее в е д ш а я в о с с т а н о в л е н и я , е с л и о п е р а ц и я не з а в е р ш е н а до конца (наярвв^ п р и а в а р и й н о м п р е р ы в а н и и о п е р а ц и и у д а л е н и я файла; в .-vicm ч а е с п р а в о ч н и к м о ж е т б ы т ь т о л ь к о ч а с т и ч н о изменен).
8.3. Содержимое и структура каталогов (словарей) К а т а л о г и ( с л о в а р и ) и д е н т и ф и ц и р у ю т файлы и их м- —i а* п о л о ж е н и я . Н а и б о л е е п р о с т о й с л о в а р ь содержит имя ф а ш и в # ф и з и ч е с к и й а д р е с н а д и с к е . С т р у к т у р а справочника к~жгт(ц 282
южнее, в нем могут храниться р а з м е р ф а й л а , его «•тупа, метки времени (дата и в р е м я с о з д а н и я , nola, последнего изменения). Т а к к а к с а м и справоч:сматривать как данные, которые я в л я ю т с я объ»v модификации, то они часто р а с с м а т р и в а ю т с я к а к пильного назначения (UNIX-подобные с и с т е м ы ) . »методы организации каталогов. (Методыорганизации каталогов
Iраспространенной является д р е в о в и д н а я с т р у к т у оторой каждая вершина дерева я в л я е т с я к а т а л о •твь указывает или на другой к а т а л о г , и л и на ф а й л ьдерева называют корневым к а т а л о г о м . Л и с т ь я м и я файлы данных. Если имена всех в е р ш и н с о д н и м то для имени файла м о ж н о и с п о л ь з о в а т ь ;шин, начиная с корневого к а т а л о г а и до л и с т а . • 'павтируется уникальность и м е н и ф а й л а . чия доступа главный справочник ( к о р н е в о й нагл, как правило, в оперативной п а м я т и . К о р н е в ы х •1 быть несколько, для каждого п о л ь з о в а т е л я свой {-подобные системы). В этом случае в о п е р а т и в н о й гея дескриптор корневого к а т а л о г а а к т и в н о г о i >криптор содержит информацию о к а т а л о г е , не•I перехода от виртуального к реальному д и с к о в о м у адресу на диске). Дескриптор ф а й л а создается, пл. Дескриптор обновляется, к о г д а и з м е н я е т с я I, -го местоположение или когда в ы п о л н я е т с я обраДескриптор файла обычно п о м е щ а е т с я в н у т р и заi.F-лп дескриптор требует много места ( ф а й л с и л ь н о 1 он может храниться отдельно. Обычно д е с к р и п ДН . ЛТСЯ в оперативной памяти, когда ф а й л о т к р ы т , независимо от файловой системы, д е с к р и п т о р соqno информацию: Мшор файла; 1 1 диске; | vna. атор файла, как правило, состоит из д в у х ч а с т е й . - имя файла, которое может быть задано к а к поло м у . Вторая часть — число, которое м о ж е т б ы т ь де открытых файлов, адресом в этой т а б л и ц е и л и 283
ч и с л о м , в ы ч и с л е н н ы м п о а л г о р и т м у , обеспечивающему 1 " ность этого числа д л я всех о т к р ы т ы х файлов. в А д р е с на д и с к е — м е с т о п о л о ж е н и е ф а й л а и его pa; • ф а й л ф р а г м е н т и р о в а н , д о л ж е н б ы т ь з а д а н адрес каждой «счг его р а з м е р . Способ з а д а н и я ф р а г м е н т и р о в а н н ы х файлов зат»г от конкретной файловой системы. П р а в а д о с т у п а — о п р е д е л я е т , к т о и к а к может с з а д а н н ы м ф а й л о м ( к а т а л о г о м ) . Ф а й л о в а я система храню ф о р м а ц и ю в з а щ и щ е н н о м в и д е и обеспечивает выполне°!'° Щ н о в л е н н ы х п р а в д о с т у п а . К э т о й и н ф о р м а ц и и относятся, гриа всего, р а з р е ш е н и е на ч т е н и е , з а п и с ь , исполнение для t файла и других групп пользователей. Д о п о л н и т е л ь н о д е с к р и п т о р м о ж е т хранить метки врвШШ а и м е н н о : д а т у с о з д а н и я ф а й л а , д а т у последнего доступа и вой» н е й м о д и ф и к а ц и и , с ч е т ч и к д о с т у п а к ф а й л у , с помощью В И И о п р е д е л я е т с я н е о б х о д и м о с т ь у н и ч т о ж е н и я дескриптора ( 1 | о д и н п о л ь з о в а т е л ь не о б р а щ а е т с я к з т о м у файлу). Ф а й л м о ж е т б ы т ь о т к р ы т к а к временный, т.е. пот-- *«ч к р ы т и я он а в т о м а т и ч е с к и у н и ч т о ж а е т с я . Признак вреимвяв файла должен храниться в дескрипторе. Ф а й л м о ж е т п р о з р а ч н о ш и ф р о в а т ь с я . В этом случа ливается соответствующий признак.
8.4. Методы работы файловой системы. Виртуальные файловые системы Р а с с м о т р и м более п о д р о б н о особенности работы п с rpv»«|[ д а н н ы х д л я в и р т у а л ь н ы х ф а й л о в ы х систем, которые п е т * и с п о л ь з о в а н и е р а з н ы х ф а й л о в ы х с и с т е м не только для дисков, но и д л я разделов д и с к а . В и р т у а л ь н а я ф а й л о в а я с и с т е м а (VFS — Virtual Fi д л я U N I X — это п р о г р а м м н о е обеспечение (часть ядра), ют у п р а в л я е т в с е м и с и с т е м н ы м и в ы з о в а м и файловых систем в О н а о б е с п е ч и в а е т о б щ и й п о л ь з о в а т е л ь с к и й интерфейс ш HI I от и с п о л ь з у е м о й Ф С . Т а к , н а п р и м е р , по команде копиров, Ш $ ср /floppy/TEST/tmp/test у с т а н а в л и в а е т с я с о о т в е т с т в и е м е ж д у дискетой с | с и с т е м о й F A T 1 2 (DOS, W I N D O W S ) и файловой сист ( U N I X ) . В э т о м с л у ч а е г о в о р я т о м о н т и р о в а н и и дискеты на, •. 284
Обращение к этому разделу ф а к т и ч е с к и соответствует кдискете. >вые системы, которые п о д д е р ж и в а ю т с я V F S , д е л я т с я
ьйкласс — дисковые ф а й л о в ы е с и с т е м ы . О н и у л р а в л я I разделами. Примерами т а к и х с и с т е м д л я L I N U X - файловые системы ЕХТ2, Е Х Т З , R e i s e r F i l e s y s t e m s А Для UNIX к этим системам о т н о с я т с я : S y s t e m V, СоМХ, UFS (BSD, Solaris, N e x t ) , ФС M I N I X , и V E R I T A S PJ UNIXWare). Для файловых с и с т е м ф и р м ы M i c r o s o f t : - rATnFAT32 (для WINDOWS 95 и более п о з д н и х в е р с и й ) llftiMDOWS NT и более поздних в е р с и й ) . Д л я CD-ROM к ®нм системам относятся ф а й л о в а я с и с т е м а I S 0 9 6 6 0 ! р же High Sierra Filesystem) и ф а й л о в а я с и с т е м а д л я Bmsal Disk Format (UDF). Ф а й л о в ы е с и с т е м ы ф и р м ы массадля OS/2 - HPFS. Д л я A p p l e ' s M a c i n t o s h — H F S , iftsiFilesystem (AFFS) и Acorn Disk F i l i n g S y s t e m (ADFS). J массу относятся журнальные ф а й л о в ы е с и с т е м ы ф и р MFSHSGI'SXFS.
iti шсс — сетевые ф а й л о в ы е с и с т е м ы . О б е с п е ч и в а ю т 1 Аловым системам компьютеров в сети. К т а к и м ф а й л о - vотносятся NFS, Coda, A F S ( ф а й л о в а я с и с т е м а A n d Е(Server Message Block, которая и с п о л ь з у е т с я M i c r o s o f t > п IBM OS/2 LAN Manager д л я р а з д е л е н и я ф а й л о в и i)и NCP (Novell's NetWare Core P r o t o c o l ) , i класс — специализированные ф а й л о в ы е с и с т е м ы , авляют дисковым пространством л о к а л ь н ы х и у д а л е н ием. что каталоги файловых с и с т е м о б р а з у ю т дере•> дерева — корневой каталог. Ф а й л о в а я система, к о т о р а я вым каталогом, называется к о р н е в о й ф а й л о в о й В качестве корневой ФС на L I N U X обычно используетНа любой подкаталог корневого к а т а л о г а м о ж е т б ы т ь ) любая файловая система из р а с с м о т р е н н ы х в ы ш е ено соответствие между п о д к а т а л о г о м и р а з д е л о м [ной ФС). После монтирования ФС о с т а л ь н ы е подкалевого каталога не видны п о л ь з о в а т е л я м с м о н т и р о в а н К.»" иосле ее демонтирования (разрыва с в я з и м е ж д у под»яФС) корневой каталог снова м о ж е т б ы т ь п р о с м о т р е н . рим ва примере команды ч т е н и я ф а й л а ф у н к ц и о н и YFS. ПУСТЬ необходимо прочитать ф а й л с д и с к е т ы , д л я 285
которой используется ФС F A T 1 2 . По команде read/1 ш с и с т е м н ы й в ы з о в sy$_read(), к а к д л я собственных ф а ! с т е м . И н ф о р м а ц и я о ф а й л е з а п и с ы в а е т с я в области пш ( с т р у к т у р а F i l e ) . С т р у к т у р а э т и х д а н н ы х рассмотрена и из п о л е й э т и х д а н н ы х — п о л е f_Op, которое содержат у -—7 н а ф у н к ц и ю ч т е н и я ф а й л а д л я Ф С F A T 1 2 . Системны! выэ read() н а й д е т а д р а с э т о й ф у н к ц и и и вызовет ее. ФАКТ п о л ь з у е т с я к о с в е н н ы й в ы з о в ф у н к ц и и read(): file->ljcp--1 М о ж н о р а с с м а т р и в а т ь ф а й л о в у ю модель как объег. i| т о р о г о о п р е д е л е н ы с т р у к т у р ы д а н н ы х и методы Ниже, | ны используемые структуры данных. СупврБлок. Х р а н и т и н ф о р м а ц и ю о смоатпроюаэ Д л я Ф С . у п р а в л я ю щ и х р а з д е л а м и д и с к а , здесь у п р а в л я ю щ и й блок соответствующей ФС. н е к о т о р ы х ф а й л о в ы х с и с т е м б у д у т рассмотрены
обычно i \ Управляв ниже. г Inode. Х р а н и т у п р а в л я ю щ у ю информацигоофаЙжСш:; с т р у к т у р о й э т о г о т и п а с в я з а н о ц е л о е ч и с л о , которое являм! к а л ь н ы м н о м е р о м ф а й л а в Ф С . Э т о т номер определяет ч , л о ж е н и е файлн на диске. File. Х р а н и т и н ф о р м а ц и ю о взаимодействии файла • I с а . Эта и н ф о р м а ц и я с у щ е с т в у е т в о б л а с т и ядра до тех да^ процесс использует ф а й л ( м е ж д у этапами открытияфайла). Dentry. И н ф о р м а ц и я о к а т а л о г е , в котором влходжтаф^ П у с т ь п о т о к п р о ц е с с а о б р а щ а е т с я к файлу. Ватомиу^ п о л н я е т с я с т р у к т у р а File, в к о т о р о й записывается иаформ! р е ж и м а х доступе т е к у щ е г о потока и друтих з а щ и т ы и т . д . По п о л н о м у и м е н и ф а й л а определяется с] Dentry. Д л я э т о й с т р у к т у р ы я д р о с т р о и т структуру /ЛОЛ.11 фактически определяет место на диске э т у и н ф о р м а ц и ю и и н ф о р м а ц и ю из суперблока, с DI ций конкретной Ф С в ы п о л н я е т с я требуемая ч т о п о л н а я и н ф о р м а ц и я о ф а й л е х р а н и т с я яа в е р ш е н и я э т о й о п е р а ц и и ( д л я э т о г о используется п к э ш ) , п р и п о в т о р н о м о б р а щ е н и и к атому п о в т о р н о г о ф о р м и р о в а н и я е г о с т р у к т у р , чтоувелвчпи доступе к диску.
потоков, мкдзи
данного фаАла li опера дня. 3< днеке •
файлу ве •
Не все о п е р а ц и и т р е б у ю т о б р а щ е н и я к функциям к Ф С . Н е п р и м е р , о п е р а ц и и о т к р ы т и я , з а к р ы т и я файла, а р о в а н и е в ф а й л е не т р е б у е т о б р а щ е н и я к этим ф д я т т о л ь к о к и з м е н е н и ю о б ъ е к т о в я д р а , которые cipom 'TJ
t -учшего понимания а р х и т е к т у р ы V F S и в з а и м о д е й с т в и я !тными ОС рассмотрим с т р у к т у р ы , п е р е ч и с л е н н ы е иее. I. Суперблок внаем, что эта структура с о д е р ж и т и н ф о р м а ц и ю о Ф С . t суперблока для LINUX VFS: BuPERBLOCK .;/«(head
5_Ы;//Указатель
на
tJs_dev;//HdeHmucpUKamop ied long s
список
суперблоков
устройства
blocksize; //Размер блока в байтах
,ned char s_blocksize_bits; // Размер блока
t jned char sjdirt; I "jried long long
//Флаг
ч
Mldgi/oUiperaf/ons
в
битах
модификации
s_maxbytes; //Максимальный
размер
*
системы
s_type; *
s_op;
//Тип
файловой
//Таблица
методов
* dq_op; // Таблица
gned long sjlags; //Флаги
файла
для
методов
суперблока
для
квоты
монтирования
. : gned long s_magic;//Уникальное число для ФС '•"•iiy'
s
root;
//Каталог
r'rwjemaphore
монтирования
s_umount;//Семафор
для
демонтирования
i\
semaphore sJock; // Семафор для суперблока
:
шик//Счетчик
использования
*""ic_ti_ac(/'ve //Дополнительный счетчик использования hrtfttjead s_dirty; //Список модифицированных /nodes vjhstjeadsJockedjnodes;
Вtetjiead sjiles; // R ilbtock dew'ce * list_head s
//
Список
Список
inodes,
файлов
для
s_bdev; //Указатель на
instances; //Указатель
•Jquota_mount_options
s_dquot;
на
//Режимы
вызвавших данного
I/O
суперблока
дескриптор драйвера список суперблоков установки
квоты
•r
Илекты суперблока записываются в ц и к л и ч е с к и й д в у х ый список. Адрес начала с п и с к а х р а н и т с я в с п е ц и а л ь ной, поэтому всегда м о ж н о п о л у ч и т ь д о с т у п ко в с е м .Списку соответствует Spinlock, к о т о р ы й з а щ и щ а е т его чтвого доступа в случае м н о г о п р о ц е с с о р н о й с и с т е м ы , ш из поля и является о б ъ е д и н е н и е м , ч т о п о з в о л я е т к-.азную информацию для р а з н ы х Ф С . Эта и н ф о р м а ц и я тФСвыполнять свои операции. Т а к к а к она о ч е н ь в а ж швает ее в оперативную п а м я т ь без д о с т у п а к д и с к у . 287
Т у д а же з а п и с ы в а ю т с я в с е о б н о в л е н и я . Конечно, ОС «олш с л е д и т ь з а т е м , ч т о б ы и н ф о р м а ц и я в п а м я т и соответствий! и н ф о р м а ц и и на д и с к е с у ч е т о м ее о б н о в л е н и я . Для решения п р о б л е м ы и с п о л ь з у е т с я ф л а г о б н о в л е н и я s_dirt, который u r e a л и в а е т с я в с л у ч а е м о д и ф и к а ц и и с у п е р б л о к а . Для уменьшена»» т е р ь , с в я з а н н ы х с н е п р е д с к а з у е м ы м к р а х о м ОС, данные н* ;я о б н о в л я ю т с я п е р и о д и ч е с к и . М е т о д ы д л я объекта «СупербяиМя т о р ы е з а д а ю т с я в с т р у к т у р е super_operations , зависят от кппфв н о й ОС. К о г д а н е о б х о д и м о в ы з в а т ь о д н у из операций для г т » б л о к а , в ы з о в в ы п о л н я е т с я т а к : s f c - > s _ о р - > ф у н к ц и я (парамщл* В э т о м о п е р а т о р е sb — а д р е с с т р у к т у р ы д л я данного cynejAna К о п е р а ц и я м д л я с у п е р б л о к а о т н о с я т с я т а к и е операции, к и IP н и е и з а п и с ь о т д е л ь н ы х ч а с т е й , т а к и х к а к таблицы расю ф а й л о в , к а т а л о г о в и т . д . , а т а к ж е о п е р а ц и и монтирования ш монтирования файловой системы. 8.4.2. Объект INODE З д е с ь с о д е р ж и т с я и н ф о р м а ц и я д л я управления дотудав» ф а й л у . К а ж д о м у ф а й л у с о о т в е т с т в у е т ровно один INODE, н~ье| к о т о р о г о не и з м е н я е т с я во все в р е м я существования фала, # з а в и с и м о от и з м е н е н и й , к о т о р ы е в н о с я т с я в файл, в том i в его и м я . С т р у к т у р а INODE в к л ю ч а е т в себя много пот и приведены только некоторые: struct { //
INODE
Указатели
на
списки
unsigned
long
i_ino;
unsigned
int
ijcount
kdevt
i_dev;
umodejt i nlink_t
i_nlink;
offjt
i_size;
//
// //
Номер
Тип
блока версии,
использовании
номер
Счетчик файла
файла
права
жестких
владельца,
/'node
использования устройства
и
Количество
// Размер
Временные
// Размер
Уникальный //
//Идентификатор
mode; //
//Идентификаторы
//
//
группы в
доступа связей и
остальныхпользовп»
байтах
метки в
битах
и
байтах
автоматически
и
количество блоков б»
увеличиваете
файла
288
при
каждой
*
для
афоры
обеспечения
fode_operations ^operations
*
эксклюзивного
доступа
* i_op; //
Таблица
операций
для
mode
ijop;////
Таблица
операций
для
файлов
ied long i_state mode; II Флаги состояния
т
на
адресное
ель на драйвер т
/node
пространство устройства
использования
т создания файла, н о м е р версии Информация.
Зависящая
от
ФС
объекте дублируется и н ф о р м а ц и я с д и с к а , н а п р и м е р , блоков для файла. Флаг с о с т о я н и я i_state п о з в о л я е т , изменилась ли и н ф о р м а ц и я в INODE, свободен и л и Е
•да для INODE включают в себя с о з д а н и е , у н и ч т о ж е шенование каталога, поиск в к а т а л о г е , и з м е н е н и е р а з доступа и атрибутов ф а й л а . 3. Объект FILE объект создается, когда поток п р о ц е с с а о т к р ы в а е т ф а й л , ется по закрытии файла. П о л я с т р у к т у р ы FILE п о л ведены ниже (см. П р и л о ж е н и е 4. С т р у к т у р ы д л я V F S ) . ены только некоторые п о л я э т о й с т р у к т у р ы
slorriictIjxiunt;//Счетчик imdejljnode; titljfjos; signed rsigned ffjm;//Kod
// Режимы
// Текущее int int
использования
fjiid, fgid; ошибки
доступа
смещение
к в
файлу файле
// Идентификатор // Идентификатор для
289
сетевой
владельца группы операции
записи
Г л а в н о й я в л я е т с я и н ф о р м а ц и я в поле file pointer — mim п о з и ц и я в ф а й л е , с к о т о р о й н а ч н е т с я выполнение очереяё о п е р а ц и и . Т а к к а к н е с к о л ь к о п р о ц е с с о в могут одноврек^яю 4 р а щ а т ь с я к о д н о м у и т о м у же ф а й л у , этот указатель не * <ат х р а н и т ь с я в о б ъ е к т е INODE. К а ж д ы й объект типа file исша^я несколько списков. 1 . С п и с о к о с о б ы х ф а й л о в ы х о б ъ е к т о в (неиспользуемш. в э т о м с п и с к е к э ш п а м я т ь д л я ф а й л о в ы х объектов и зареэсгчр» в а н н а я п а м я т ь д л я с у п е р п о л ь з о в а т е л я , она позволяет суперж» з о в а т е л ю о т к р ы т ь ф а й л д а ж е в т о м с л у ч а е , если динамич^вд п а м я т ь в с и с т е м е и с ч е р п а н а . Т а к к а к о б ъ е к т ы отмечены KIU. М» п о л ь з у е м ы е , их с ч е т ч и к и с п о л ь з о в а н и я fjcount = 0. 2. С п и с о к и с п о л ь з у е м ы х ф а й л о в ы х объектов, коториепш н е з а д е й с т в о в а н ы с у п е р б л о к о м . П о л е f_COunt для этих объела равно 1. 3. С п и с к и и с п о л ь з у е м ы х ф а й л о в ы х объектов, которы» f< з а д е й с т в о в а н ы с у п е р б л о к а м и . К а ж д ы й суперблок хранит в ж s_files а д р е с н а ч а л а с п и с к а ф а й л о в ы х объектов, файловые dk е к т ы д л я р а з л и ч н ы х ФС з а п и с ы в а ю т с я в разные списки. Сьв f_count д л я к а ж д о г о э л е м е н т а т а к о г о с п и с к а равно 1 + числг. гр» цессов, и с п о л ь з у ю щ и х з т о т ф а й л . С е м а ф о р files lock з а щ и щ а е т с п и с к и от конкурентного па в м н о г о п р о ц е с с о р н ы х с и с т е м а х . К а к п о к а з а н о р а н е е , к а ж д о й Ф С соответствует множн-г» ф а й л о в ы х о п е р а ц и й д л я ч т е н и я и з а п и с и файлов. Когда яду» з а г р у ж а е т INODE в п а м я т ь с д и с к а , он записывает адреса им» в е т с т в у ю щ и х ф у н к ц и й в с т р у к т у р у file_operations, адрес 1 >i з а п и с ы в а е т с я в п о л е i_fop объекта inode. Когда процесс от* ф а й л , V F S и н и ц и а л и з и р у е т п о л е f op нового файлового обълЦ з а п и с ы в а я т у д а а д р е с из INODE, п о э т о м у все дальнейшие вы пш п р и в о д я т к о б р а щ е н и ю к ф у н к ц и я м соответствующей ФС. Ф а й л о в ы е о п е р а ц и и в к л ю ч а ю т в себя операции открыт»» • з а к р ы т и я ф а й л а , ч т е н и я , з а п и с и и позиционирования в файле 8.4.4. Объекты типа DENTRY V F S р а с с м а т р и в а е т к а т а л о г к а к ф а й л , содержащий спил» ф а й л о в и в л о ж е н н ы х к а т а л о г о в . Б у д у ч и прочитанным в nawrrv к а т а л о г п р е о б р а з у е т с я V F S в о б ъ е к т т и п а DENTRY. Поля стяр т у р ы о б ъ е к т а т и п а DENTRY п о л н о с т ь ю з а д а н ы в Приложении! С т р у к т у р ы д л я V F S , з д е с ь п р и в е д е н ы т о л ь к о некоторые поля. 290
WENTRYf ffl/cj d_count;
// Счетчик использования
•Mtinode'djnode;IIInode
для
файла
•,\ctdentry'd_parent;/IDentry-o6beKm для родительского II
•ucihsthead
каталога
d_subdirs,
IIДля
II
каталогов,
список
dentry-объвктов
подкаталогов
vxlqstrd_name; II Имя файла vet dentry operations* d_op;
// Функции
Г ctsuper_block * d_sb; II Объект d'dfsdata;//Данные, jvigred char
которые
* djname;
//Адрес
для
Dentry
Superblock
зависят короткого
от
файла ФС
имени
файла
г. создает объект типа DENTRY д л я к а ж д о г о к о м п о н е н т а [йла, с которым работает п р о ц е с с . Н а п р и м е р , к о г галога /tmp/test, то создаются т р и о б ъ е к т а т и п а DENTирневого каталога (ему соответствует с и м в о л / ) , д л я подI'TJJ корневого каталога и п о д к а т а л о г а test д л я к а т а л о г а •"им, что объектам типа DENTRY не с о о т в е т с т в у ю т п о л я ВМгому дштаких полей нет п р и з н а к о в , к о т о р ы е у с т а н а в • три изменении объекта. Эти о б ъ е к т ы х р а н я т с я в д и н а i памяти — специальном к э ш е д л я о б ъ е к т о в этого т и п а , ый объект типа DENTRY может б ы т ь в о д н о м из 4 - х соКое. Объект не используется V F S . С о о т в е т с т в у ю щ а я 1НЙТИуправляется модулями у п р а в л е н и я п а м я т ь ю . I гсшьзуется. Объект сейчас не и с п о л ь з у е т с я я д р о м , («пользования d count = 0, но п о л е d_inode е щ е у к а з ы в а гатвующий INODE. Объект с о д е р ж и т в е р н у ю и н ф о р |. то содержимое может быть с б р о ш е н о п р и н е о б х о д и м о дения памяти. шзуется. Объект и с п о л ь з у е т с я я д р о м . С ч е т ч и к и с кмя djount > О, объект содержит в е р н у ю и н ф о р м а ц и ю быть сброшен. ирный. INODE, соответствующий DENTRY, не с у щ е с т в у I мзи с тем, что диск, соответствующий INODE, б ы л у д а »т> ..сак объект DENTRY был создан п р и а н а л и з е к а т а л о г а 291
д л я н е с у щ е с т в у ю щ е г о ф а й л а . П о л е d_inode устанавливает н ы м NULL, но о б ъ е к т все е щ е о с т а е т с я в кэше объектов DEI-"т а к ч т о о п е р а ц и и с т а к и м и м е н е м к а т а л о г а могут быть быстр I. полнены. Т а к к а к ч т е н и е к а т а л о г а с д и с к а и создание соответстмм» го о б ъ е к т а т и п а DENTRY т р е б у е т значительного времени, ш с м ы с л х р а н и т ь в п а м я т и о б ъ е к т ы д а ж е после завершения уЛг т ы с н и м и н а с л у ч а й , е с л и э т и ж е о б ъ е к т ы будут использоыг-^ в д а л ь н е й ш е м . К п р и м е р у , ф а й л ы после редактирования к л и р у ю т с я , а р х и в и р у ю т с я и т . д . Д л я э т и х целей ОС испоы.. к э ш д л я х р а н е н и я о б ъ е к т о в т и п а DENTRY. В кэше хранятс . ' е к т ы , к о т о р ы е н а х о д я т с я в о д н о м из 4 состояний, рассмотрев ш в ы ш е . Д л я о б е с п е ч е н и я б ы с т р о г о д о с т у п а к объекту типа DE ПЯ п о з а д а н н о м у и м е н и ф а й л а к э ш м о ж е т хранить хеш-т»й,,н Е с л и с о о т в е т с т в у ю щ е г о о б ъ е к т а в к э ш е у ж е нет, в хеш-та щу х р а н и т с я 0 в м е с т о у к а з а т е л я на этот объект. Заметим, ч^о DENTRY в к э ш е , с о о т в е т с т в у ю щ и й е м у INODE тоже н м ш р в п а м я т и я д р а , т а к к а к с ч и т а е т с я з а н я т ы м и не может быть ш е н н ы м . Все DENTRY-объекты, к о т о р ы е находятся в составо « Н е и с п о л ь з у е т с я » , з а п и с ы в а ю т с я в с п и с о к , в котором ОС наг « ж е р т в ы » д л я о с в о б о ж д е н и я к э ш - п а м я т и по алгоритму «Leu11» c e n t l y U s e d » ( н а и б о л е е д о л г о не и с п о л ь з у е м ы й ) , если этой пмага не х в а т а е т . В L I N U X и с п о л ь з у е т с я т а к о й алгоритм для ра с д а н н ы м с п и с к о м . А д р е с н а ч а л а и к о н ц а списка запнсымга в с п е ц и а л ь н ы е п е р е м е н н ы е . П р и з а н е с е н и и объекта типа DEN в к э ш он з а н о с и т с я в н а ч а л о э т о г о с п и с к а . П р и использованлв Ш го о б ъ е к т а его а д р е с н а х о д и т с я в с п и с к е и переносится в его л о . В э т о м с л у ч а е в к о н ц е с п и с к а всегда будут элементы, кг— . н е и с п о л ь з о в а л и с ь н а и б о л е е д о л г о . Д л я з а щ и т ы кэш-пам'— к о н к у р е н т н о г о и с п о л ь з о в а н и я в многопроцессорной систе» - q | м е н я е т с я spin lock cachelock. Ф у н к ц и и д л я к а т а л о г о в в к л ю ч а ю т в себя создание, уд_. сравнение и другие, з а в и с я щ и е от ФС функции.
8.5. Монтирование и демонтирование ФС К а ж д о й ФС с о о т в е т с т в у е т с в о й к о р н е в о й каталог. ФС, i <•;• н е в о й к а т а л о г к о т о р о й я в л я е т с я с и с т е м н ы м корневым ката i » н а з ы в а е т с я к о р н е в о й Ф С . Д р у г и е ФС м о г у т быть смонтированы и к а т а л о г и в с и с т е м н о м д е р е в е . К а т а л о г , в который вставлена «К 292
"я точкой монтирования. С м о н т и р о в а н н а я ФС я в л я е т с я ФС, в каталог которой вставлена н о в а я ФС. ер. Виртуальная файловая система /ргос я в л я е т с я покорневой ФС (и Корневая ФС я в л я е т с я р о д и т е л е м ФС ]зя большинства UNIX-подобных я д е р с к а ж д ы м к а т а лот быть связана только одна ФС. Т а к , после к о м а н д ы : iri-text2/dev/fdO/ftp,
•
каталог /dev/fdO монтирует ф а й л о в у ю систему д л я рахетой, обращение к каталогу /dev/fdO я в л я е т с я ошибпор.покане будет использована к о м а н д а д е м о н т и р о в а Некоторые ОС разрешают повторное м о н т и р о в а н и е Ф С . ванного выше следует, что ФС, о б о з н а ч и м ее д л я опреТА ФС1, может быть смонтирована на к а т а л о г к о р н е в о й D обозначим ФСО. ФС2 м о ж е т быть с м о н т и р о в а н а на ФС1 и т.д. каждой операции монтирования я д р о д о л ж н о с о х р а н и т ь точку монтирования и и н ф о р м а ц и ю о с м о н т и р о в а н н о й информация записывается в с т р у к т у р у , к о т о р а я н а з ы 9»криптором смонтированной ФС. -Т-гаурв дескриптора для текущей ФС:
i.:VFSMOUNT{ !_head mnt_hash; Amount
II
Gentry' mntmountpoint; ткия текущей Jentry'
Указатели
* mnt_parent;
mntjoot,
на
хеш-таблицы
II
Указатели
на
Н
Указатели
на
родительскую dentry
ФС
каталога
ФС
II
Указатели
mnt_sb;ll
Указатели
на
dentry
корневого
каталога
щейФС ijperjlock' г..
,t_bead mntjnounts; (относительно
виршюроа
stjead
mnt_child;
w.aunmорое fjrmt_ccunt;
текущей
//Указатели
(относительно II
Счетчик
на
// Вершина
superblock
текущей
родительского
ФС
списка
ФС)
для
родительского
родительской
списка
ФС)
использования
\Jags Flags; 1/Флаги
'mjdewame; II Имя ФУ f-
ijead mntjist;
II
Указатели
на
глобальный
список
торов -^ухтура данных в к л ю ч а е т в с е б я д в у н а п р а в л е н н ы е
Пибальный список, который включает в себя д е с к р и п т о ^втированных ФС. 293
2. Х е ш - т а б л и ц у с а д р е с а м и д е с к р и п т о р а типа vfsmountp а т е л ь с к о й Ф С и а д р е с о м о б ъ е к т а т и п а dentry точки монтировав Эта т а б л и ц а х р а н и т с я в о п е р а т и в н о й п а м я т и . Каждый ме»Ш т а б л и ц ы — в е р ш и н а ц и к л и ч е с к о г о 2-направленного списка, s;> нящего список всех дескрипторов. 3. Д л я к а ж д о й с м о н т и р о в а н н о й ФС циклический 2-нагри л е н н ы й с п и с о к , в к л ю ч а ю щ и й в с е с м о н т и р о в а н н ы е ФС-потсмп 8.5.1. Монтирование корневой ФС В ы п о л н я е т с я п р и и н и ц и а л и з а ц и и ОС. В качестве ко] ФС м о г у т и с п о л ь з о в а т ь с я р а з д е л ж е с т к о г о диска, гибкий у д а л е н н ы й д и с к и л и д а ж е о п е р а т и в н а я п а м я т ь , которая H W е т с я к а к д и с к . В д а л ь н е й ш е м б у д е м предполагать, что в качкя к о р н е в о й ФС и с п о л ь з у е т с я р а з д е л ж е с т к о г о диска. Корне м о ж е т б ы т ь з а д а н а к а к ФУ в к а т а л о г е /dev. Аналогично 4 М м о н т и р о в а н и я к о р н е в о й ФС х р а н я т с я в специальной перекмМ к о т о р а я з а д а е т с я к о м п и л я т о р у я д р а и л и загрузчику ОС М о н т и р о в а н и е к о р н е в о й Ф С в ы п о л н я е т с я 2-этапной цией. 1. Я д р о м о н т и р у е т с п е ц и а л ь н у ю ФС с пустым корневых» талогом, которая запоминает точку монтирования. 2. Я д р о м о н т и р у е т р е а л ь н у ю к о р н е в у ю ФС поверх пупв каталога. З а ч е м с п е ц и а л ь н а я Ф С м о н т и р у е т с я перед реальной? С v n а л ь н а я ФС облегчает п р о ц е д у р у у с т а н о в к и реальной корнек Ф В с а м о м д е л е , в н е к о т о р ы х с л у ч а я х я д р о монтирует и демонтда н е с к о л ь к о Ф С , о д н у п о с л е д р у г о й . К п р и м е р у , сначала устшш в а е т с я ФС на г и б к о м д и с к е д л я з а г р у з к и я д р а ОС с минпма.. ч и с л о м д р а й в е р о в , э т а ФС з а п и с ы в а е т с я в оперативную пам1> З а г р у ж е н н ы е м о д у л и о п р е д е л я ю т т и п ж е с т к о г о диска, загрум» все н е о б х о д и м ы е м о д у л и я д р а и п е р е м о н т и р у ю т ФС для жгтмш диска. П е р в а я с т а д и я о п е р а ц и и м о н т и р о в а н и я выполняет с ; т • щие шаги. 1. П р о в е р я е т , и м е е т ли т е к у щ и й процесс достаточно ij» в и л е г и й д л я в ы п о л н е н и я ф у н к ц и и м о н т и р о в а н и я (эта про*?,г»в с е г д а п о л о ж и т е л ь н а , т а к к а к и н и ц и а л и з а ц и ю ОС выполвв» суперпользователь). 2. В ы п о л н я е т п о и с к т р е б у е м о й Ф С . Ф у н к ц и я поиска в< р щ а е т д е с к р и п т о р д л я з а д а н н о г о т и п а ФС. 294
Выделяет память д л я д е с к р и п т о р а н о в о й ФС и з а п и с ы в а е т "памяти.
Еищшлизирует в этой памяти поле mnt_devname, опредемяустройства для ФС. еляет память для нового суперблока и и н и ц и а л и з и р у псываетадрес суперблока в поле дескриптора ФС. Формирует поля дескриптора, в к о т о р ы х о п р е д е л я ю т с я ' каталог и точка монтирования, з а п и с ы в а я туда адрес ms DENTRY, соответствующей ФС. дарует поле родительской ФС, которое равно адресу текущей ФС, так как это корневая ФС и родителя не ждает семафор, который использовался п р и выполкта 5. Возвращает адрес дескриптора ФС. " я стадия операции монтирования в ы п о л н я е т с я в к о н ц е Нмции ОС. Сселяется буфер, в который записывается список и м е н (Г Этот список либо сообщается программе и н и ц и а л и з а рмируется ею сканированием скомпонованных типов 1
Ьшвает функцию для проверки н а л и ч и я и работоспособ"jBnoro устройства. 1Ь.лшет функцию для поиска суперблока д л я заданного в списке суперблоков. Обычно ф у н к ц и я находит это ке выполнена первая стадия ( к а к правило, к о р н е в а я уется 2 раза в течение з а г р у з к и : с н а ч а л а в р е ж и м е чтения», так что ее целостность гарантируется; а зае «Чтение и запись», чтобы м о ж н о было использовать ьном режиме). Предположим, что требуемый суперйден в списке суперблоков. Сширует список с именами типов ФС, построенных на г?. Для каждого типа определяет адрес объекта и вы|рщию для чтения суперблока. Эта ф у н к ц и я м о ж е т заблагополучно только для того т и п а ФС, д л я которой шаг 1. Для данной ФС будут созданы объекты INODE и я корневого каталога; устанавливается с в я з ь м е ж д у тамп. -ляется память для вновь смонтированной ФС, в кото"ются адрес соответствующего устройства, супербло>в типа INODE и DENTRY. 295
6. А д р е с о б ъ е к т а д л я в н о в ь с м о н т и р о в а н н о й системы м с ы в а е т с я к а к а д р е с п о т о м к а д л я Ф С , смонтированной на шаг"1 в о б щ и й с п и с о к с м о н т и р о в а н н ы х ФС и в хеш-таблицу для сморованных ФС. 7. У с т а н а в л и в а е т с я п о л е к о р н е в о г о каталога для тек ^ п р о ц е с с а ( п р о ц е с с /л/08.5.2. Монтирование обычной ФС О б ы ч н а я ФС м о ж е т б ы т ь с м о н т и р о в а н а только после ж т и р о в а н и я к о р н е в о й Ф С . К а ж д а я ФС д о л ж н а иметь свой кя , ( т о ч к у м о н т и р о в а н и я ) , к о т о р ы й у ж е д о л ж е н существовать. Л а монтирования ФС задаются: — Ф У , к у д а в ы п о л н я е т с я м о н т и р о в а н и е (задается во с л у ч а я х , к р о м е м о н т и р о в а н и я с е т е в о й ФС); — точка монтирования; — т и п ФС, к о т о р ы й д о л ж е н б ы т ь з а д а н именем зарегн ГЩ рованной ФС; — ф л а г и м о н т и р о в а н и я ( т о л ь к о д л я чтения, запрет заг DI и д е н т и ф и к а т о р о в в л а д е л ь ц а и г р у п п ы , з а п р е т на выполнени' — у к а з а т е л ь на с т р у к т у р у д а н н ы х , которые зависят Ф ( м о ж е т б ы т ь 0). Ф у н к ц и я к о п и р у е т з н а ч е н и я п а р а м е т р о в во временив * ф е р в я д р е ОС. С и с т е м н а я ф у н к ц и я sys__mount() выполняет п» монтирование, а именно: — в с о о т в е т с т в и и с з а д а н н ы м и ф л а г а м и по ограничен!'' . с т у п а у с т а н а в л и в а е т ф л а г и в о б ъ е к т е монтированной ФС; — выполняет поиск точки монтирования; — а н а л и з и р у е т ф л а г и м о н т и р о в а н и я д л я определения что д о л ж н о быть сделано. 8.5.3. Демонтирование ФС И с п о л ь з у е т с я , е с л и д а н н а я ФС у ж е не нужна. Для ф\'вг я з а д а е т с я д в а п а р а м е т р а : и м я ф а й л а ( и л и каталог монтиро- 1 • и л и Ф У ) и ф л а г и . Ф у н к ц и я д е м о н т и р о в а н и я выполняет i щие действия: — и щ е т т о ч к у м о н т и р о в а н и я ; е с л и соответствующей I м о н т и р о в а н и я не н а й д е н о — в о з в р а щ а е т ошибку; — е с л и п о л ь з о в а т е л ь не и м е е т п р а в д л я монтирования к . м о н т и р о в а н и я Ф С , т о ф у н к ц и я в о з в р а щ а е т ошибку; — и щ е т адрес с у п е р б л о к а д л я ФС, к о т о р а я должна бь. . ? монтирована; 296
-е ли демонтируется к о р н е в а я Ф С , р е ж и м д о с т у п а к н е й на режим «Только д л я ч т е н и я » ; наделяет семафор для з а п и с и и Spinlock д л я д о с т у п а к объЕ1 dentry; - ила ФС не имеет с м о н т и р о в а н н ы х п о т о м к о в и л и е с л и :>льуказал режим д е м о н т и р о в а н и я в м е с т е с п о т о м к а м и , адемонтируется; >- «вобождаются семафор и Spinlock.
1.6.Стандартные методы реализации ' чожно разложить на р я д у р о в н е й , в х о д я щ и х в с о с т а в а'еской структуры от самого н и з к о г о у р о в н я н е п о с р е д о ноступа к физическому у с т р о й с т в у до п о л ь з о в а т е л ь с к о йса. Каждый уровень я в л я е т с я а б с т р а к т н о й ф а й л о в о й В1 и реализует набор процессов. С в я з и м е ж д у у р о в н я м и еы. Могут пересылаться д а н н ы е т о л ь к о в н у т р и з а д а н I или на смежные уровни. В э т о м с л у ч а е м о ж н о с к о н иь усилия на разработке к о н к р е т н о г о у р о в н я и не за'тдругих. "вая система может быть п р е д с т а в л е н а с п о м о щ ь ю слеровней. 6.1.Логическая о р г а н и з а ц и я
лзация функций, о б е с п е ч и в а ю щ и х п о л ь з о в а т е л ь с к и й c(fopen,fclose,...).
вым данным является и м я ф а й л а . По и м е н и ф а й л а гея устройство, файловая с и с т е м а , ... 1.2. Поиск по каталогу
v
ветствии с файловой системой о п р е д е л я е т с я с т р у к т у р а I. По каталогу определяется адрес ф а й л а на д и с к е . П о и с к тся по имени файла. Ф о р м и р у е т с я д е с к р и п т о р ф а й л а , на диске, где находится ф а й л . 4.6.3. Базовая файловая с и с т е м а
июлняется проверка прав доступа к ф а й л у . В ы п о л н я е т с я t (закрытие) файла. П о л у ч а е м п о л н о с т ь ю д е с к р и п т о р 297
8.6.4. Физическая организация З а п р о с ы по л о г и ч е с к и м а д р е с а м преобразуются в запрве| г ф и з и ч е с к и м а д р е с а м . На э т о м э т а п е распределяются буфе е д а - в ы в о д а . О п р е д е л я е т с я в с я ц е п о ч к а ф и з и ч е с к и х адресов 8.6.5. Физический ввод-вывод З а п р а ш и в а е м а я о п е р а ц и я п р е о б р а з у е т с я в физпческ р а ц и ю в в о д а - в ы в о д а н а у р о в н е B I O S и л и контроллера. 8.6.6. Планирование и управление вводом-выводом На э т о м у р о в н е п р о и с х о д и т непосредственная работа r п д я м и з а п р о с о в , п л а н и р о в а н и е , з а п у с к , контроль выполвеь просов. З д е с ь ф а к т и ч е с к и в ы п о л н я ю т с я обработчики прерь vtrt д л я в н е ш н и х устройств.
8.7. Примеры файловых систем 8.7.1. Структура файловой системы для ОС UNIX ОС U N I X п о д д е р ж и в а е т м н о г о р а з л и ч н ы х файловых cm -ч З д е с ь будет р а с с м о т р е н а с т а н д а р т н а я ф а й л о в а я система ОС I AT&T. ФС м о ж е т б ы т ь у с т а н о в л е н а на д и с к целиком или на ч а с т ь ( р а з д е л ) . Р а з д е л д е л и т с я н а б л о к и (рис. 8.1). Блок начальной загрузки Суперблок С п и с о к и н д е к с н ы х дескрипторов INode Данные Косвенные блоки Свободные б л о к и Р и с . 8 . 1 . С т р у к т у р а ФС д л я ОС U N I X
Б л о к 0 н а з ы в а е т с я б л о к о м н а ч а л ь н о й загрузки и исполы с я д л я з а г р у з к и ОС. С а м о й Ф С э т о т б л о к н е используется. Ра'п б л о к а з а в и с и т о т в е р с и и ОС. 298
• 'и 1 называется суперблоком (заголовок д л я ФС). В этом вржится информация о р а з м е р е р а з д е л а , р а з м е р е б л о к а вых дескрипторов (сл. ниже), и н ф о р м а ц и я о с в о б о д н ы х .1 я др. Система использует этот блок д л я п о с т р о е н и я с п и с к а х и занятых блоков. : 2. Список индексных дескрипторов. Д л я к а ж д о г о файi один и только один д е с к р и п т о р . Д е с к р и п т о р з а н и м а е т I. Дескриптор содержит и н ф о р м а ц и ю о ф а й л е : п файла (обычный, каталог, специальный),яентификаторы владельца ф а й л а и г р у п п ы ; од защиты; | - Цело жестких связей (на один и тот же ф а й л м о ж е т б ы т ь 0 ссылок, которые позволяют у п р о с т и т ь доступ к одному (Г -,ефайлу в разных проектах); Ммер файла; 1 «генные метки (время последнего доступа, последнего • информация о р а з м е щ е н и и ф а й л а на д и с к е , юрмадия о р а з м е щ е н и и ф а й л а н а д и с к е з а д а е т с я к а к
дресов на диске. Под список в ы д е л я е т с я 13 элементов. 10 элементов соответствуют ф р а г м е н т а м ф а й л а . Р а з м е р зависит от ФС и по умолчанию р а в е н 1 0 2 4 б а й т а . Тахта, если размер файла не п р е в ы ш а е т 10240 б а й т , то д л я л файла достаточно одного дескриптора. Е с л и р а з м е р файе 10 блоков, то 11 блок используется д л я з а д а н и я косвенапервого уровня. Это адрес области д и с к а , где н а х о д и т мация об очередных 256 блоках ф а й л а . Т а к и м образом, "ный размер файла, который м о ж н о з а д а т ь с п о м о щ ь ю "о дескриптора и косвенного адреса 1 у р о в н я , р а в е н • ."'>6 * 1024 = 272384 байт. Если ф а й л имеет б о л ь ш и й разпользуется 12 блок, который с о д е р ж и т к о с в е н н ы й адрес и, который, в свою очередь, содержит 2 5 6 адресов перво. Это позволяет увеличить д о п у с т и м ы й р а з м е р ф а й л а 4 *210, или до 226. Если и этого р а з м е р а недостаточно, "-уется 13 элемент дескриптора, с о д е р ж а щ и й к о с в е н н ы й Ккэвня, и размер файла может быть у в е л и ч е н на 2 8 * 2 8 * Г или до 234. Речевые дескрипторы сначала з а д а ю т с я д л я к о р н е в о г о Чанных содержит данные файлов. В с в я з и с д и н а м и ч е |р"чшем файлов этот блок не н е п р е р ы в н ы й . Свободные 1» Ччзуют список свободных блоков. 299
Д л я КАЖДОГО э л е м е н т а к а т а л о г а з а д а е т с я 2 поля: его и ш и и м я , п о д к о т о р ы м э л е м е н т и с п о л ь з у е т с я в данном к т ^ Ь Структура элемента каталога: stmc ({
}:
int char
indNode: 'FileName.
Е с л и д л я д в у х п о л е й в р а з н ы х к а т а л о г а х задан одни я д а о и н д е к с , т о ф а к т и ч е с к и э т о с с ы л к а н а о д и н и т о т ж е файл, в е ш п мо от его и м е н и . Т а к к а к ч и с л о ссылок указывается в индексе*» с к р и п т о р е , т о п р и у д а л е н и и ф а й л а ф а к т и ч е с к о е его у далеки f i ) * r в ы п о л н е н о т о л ь к о в с л у ч а е о т с у т с т в и я дополнительных о м е Доступ к ф а й л у в ы п о л н я е т с я в т а к о й последователей* п о к а т а л о г у , в к о т о р о м з а д а н ф а й л , о п р е д е л я е т с я индекса »с к р и п т о р д л и э т о г о к а т а л о г а . И с п о л ь з у я и н д е к с н ы й дес! ; « ) % с и с т е м а н а х о д и т и н д е к с т р е б у е м о г о ф а й л а . П о индексной?* с к р и п т о р у д а н н о г о ф а й л а о п р е д е л я ю т с я п р а в а доступа для пл. Е с л и п р а в а д о с т у п а п о з в о л я ю т , о п р е д е л я ю т с я ыестополояя* ф а й л а на д и с к е и доступ к н е м у . В U N I X у с т р о й с т в о р а с с м а т р и в а ю т с я к а к специальны» л ы . К а ж д о м у у с т р о й с т в у , в т о м ч и с л е и о п е р а т и в н о й niuwtt.eответствует одна з а п и с ь в и н д е к с н ы х дескрипторах. э т о м у с у с т р о й с т в а м и м о ж н о р а б о т а т ь к а к с ф а й л а м и . Та*, мя ж е с т к о г о д и с к а е г о м о ж н о р а с с м а т р и в а т ь к а к ф а й л и читап " в с о д е р ж и м о е , р а с с м а т р и в а я к а к з а п и с ь о д и н сектор. т а к ж е м о ж н о р а б о т е т ь к а к с ф а й л а м и . Т а к и м обрезом, обрели» к д р а й в е р у т о ж е р а с с м а т р и в а е т с я к а к о б р а щ е н и е к фа&г, Jbд е к с н ы й д е с к р и п т о р д л я у с т р о й с т в а с о д е р ж и т класс устро1спь е г о т и п и н о м е р . К л а с с у с т р о й с т в а — у с т р о й с т в о символьммея б л о ч н о е . Т и п з а д а е т с я н о м е р о м . Е с л и т е к и х устройств иесксои», т о , к р о м е т и п а , е щ е о п р е д е л я е т с я е г о н о м е р , ни пример, для » с к о л ь к и х ж е с т к и х д и с к о в з а д а ю т с я т и п и е г о номер. р а з о м , т и п и н о м е р п о з в о л я ю т о д н о з н а ч н о определитьytrrpoln» Н о б о л е е ч а с т о и с п о л ь з у е т с я р е ж и м д о с т у п а к диску ш к памяти. Такой режим использования ф а й л о в ыа п а м я т ь и будет рассмотрен н и ж е .
Благе-
С оаыжт»
Тали Л t
вазывоетсяотображдаеа |
8.7.2. Ф а й л о в ы е с и с т е м ы т и п а FAT И с п о л ь з у ю т с я 3 в о р с и н ф а й л о в ы х с и с т е м : F A T 1 2 — длдаж кеты, FAT — д л я в и н ч е с т е р о в н е б о л ь ш о г о размера, д л я винчестера большого размера.
16
FAT3.
300
pa диска с файловой системой т и п а F A T : ючная область (BOOT); una размещения файлов (File Allocation Table — FAT); м каталог (ROOT); кть данных. иная область (ВООТ-сектор), к р о м е п р о г р а м м ы п а узки, содержит данные с и н ф о р м а ц и е й о д и с к е . Эти лючают с себя размер с е к т о р а , к о л и ч е с т в о с е к т о р о в размеры остальных областей: т а б л и ц ы р а з м е щ е н и я >ряевого каталога. Структура BOOT-сектора д л я F A T 1 2 гШ{ •
lEimp(3];//Команда
•IEIDName[8j;
перехода
/IИмя
на
системы,
программу
которая
t'IDBytesPerSector; //Количество
байт
начальной
в
секторе
^ESectorsPerCluster;
/I Количество
секторов
в
II Количество
секторов
перед
y fENunberofFATs; // Количество таблиц
FAT
KH€RootEntries; II Число
корневом
элементов
/IКоличество
NEMediaDescriptor; II Код
диска
SectorsPerFAT; И Количество ^RDHumberofHeads;
в
секторов сторон
Количество
кластере первой
FAT
каталоге маленьких
дисков
формата
секторов
II Количество II
дпя
заданного
I'W SectorsPerTrack; // Количество MRDHiddenSectors;
в
секторов
диск
(512)
VMReservedSectors;
HCfVSrnallSeclors;
загрузки
форматировала
одной на
на
скрытых
таблице
FAT
дорожке
диске секторов
'.fORDLargeSectors; IIКоличе NEPhysicalDriveNumber;
II
Номер
физического
устройства
с ТЕ Reserved; // Резервируется •TEExlendedBootSignature;
l/28h
or
29b
Признак
расширенного
раздела WORD VclumeSerialNumber; // Серийный ?
номер
диска
'EVo!urneLabel[11j; II Метка диска
BYTEFileSystem[8];
II Идентификатор
файловой
системы
[ Jeопределения номера с е к т о р а , с к о т о р о г о н а ч и н а е т с я т а »;'ЛТ, используется ф о р м у л а :
FirstFatSector = ReservedSectors; i аскеты 1.44 Мбайт — FirstFatSector = 1. «определения номера с е к т о р а , с к о т о р о г о н а ч и н а е т с я к о р птвлог, используется ф о р м у л а :
MSector=FirstFatSector + NumberofFATs * SectorsPerFAT; 301
и
Д л я д и с к е т ы 1 . 4 4 Мб — NumberofFATs = 2; SectorsPerFAT • • FirstRootSector -17.
Д л я о п р е д е л е н и я р а з м е р а к о р н е в о г о каталога испо формула: SectorsPerRoot = SizeRootEntries * 321/ BytesPerSector Д л я д и с к е т ы 1 . 4 4 М б а й т — SizeRootEntries = 112: & И PerRoot =112*32/512 = 7. Д л я о п р е д е л е н и я н о м е р а с е к т о р а , с которого нач н 11 данные, используется формула: FirstDataSector - FirstRootSector + SectorsPerRoot; Д л я д и с к е т ы 1 . 4 4 М б а й т — FirstDataSector =17 + 7=24 Функция для определения адресов разделов дискеты с FATИ void AddressesFind (BOOT &b, DWORD& FatAddr, DWORD,& RootAddr, DWORD& DataAddr){ FatAddr = b.ReservedSectors; RootAddr = FatAddr + 2* b. SectorsPerFAT; DataAddr = RootAddr + (b.RootEntries * 32)/b. BytesPerSector
} Т а б л и ц а р а з м е щ е н и я ф а й л о в с о д е р ж и т списки KJ. д л я ф а й л о в и к а т а л о г о в . К а ж д ы й очередной элемент табп л д е р ж и т н о м е р с л е д у ю щ е г о к л а с т е р а и л и п р и з н а к конца фай. т а л о г а ) . В з а в и с и м о с т и от в е р с и и ф а й л о в о й системы для эл° э т о й т а б л и ц ы о т в о д и т с я 12, 16 и л и 32 бита. Первые 2 эле ' • т а б л и ц ы с о д е р ж а т с л у ж е б н у ю и н ф о р м а ц и ю , первому д а н н ы х с о о т в е т с т в у е т э л е м е н т т а б л и ц ы № 2. Д л я установи: о т в е т с т в и я м е ж д у н о м е р о м с е к т о р а и н о м е р о м элемента в т"бч» FAT используется формула: lndexPerFat =
(DataSector —
FirstDataSector)
SectorsPerCluster
+2;
Пример. О п р е д е л и м н о м е р э л е м е н т а в таблице FAT, с к •> р о г о н а ч и н а е т с я с п и с о к д л я ф а й л а , е с л и ф а й л начинается с т » ра № 31 на д и с к е т е . И з в е с т н о , ч т о к о л и ч е с т в о секторов в к. р а в н о 1. 1
32 — размер одной строки корневого каталога в байтах. 302
b f a ( = (31 - 2 4 ) / 1 + 2 = 9. 1ыкдом элементе таблицы у к а з ы в а е т с я н о м е р о ч е р е д н о г о файла. Например, е с л и п р е д ы д у щ и й ф а й л з а н и м а е т , которые расположены на д и с к е д р у г за д р у г о м , то »;FAT10 = 11; FAT 11 = 12. Д л я п о с л е д н е г о 12 э л е м е н т а [ается признак конца (1 во всех б и т а х ) , т . е . д л я д и с к е = 0XFFF. Если файл ф р а г м е н т и р о в а н , то з а п о л н я ю т с я отельные элементы т а б л и ц ы F A T . ям, что количество битов в с т р о к е F A T о п р е д е л я е т м а к еколичество элементов в этой т а б л и ц е . Т а к , д л я F A T 12 -ю элементов в таблице 2 1 2 , и л и 4 0 9 6 , п о э т о м у п р и р а з юдин сектор м а к с и м а л ь н ы й р а з м е р д и с к е т ы — 2 1 2 I. ЕЛЕ 212 * 2 9 -= 2 2 1 , или 2 М б а й т . Д л я у в е л и ч е н и я р а з м е р а . южно увеличить размер к л а с т е р а (2 с е к т о р а ) и л и р а з м е р | ''024бита). ции для чтения записи таблицы FAT для дискеты L FalRead (DWORD
FatAddr,
DWORD
FatSize,
BYTE
*Fat,
*W S, DWORD H){
' DRDiJ; WORD U s ; db: •0,j-FatAddr;
i
i++,j++){
UtoFA(j. h. t, s, H, S); b=ReedSector(0, h, t, s, Fat); Щ return false; a(+=5f2;
- •") true:
Л Л FatUnpack (BYTE *Fat, r
DWORD
mD Len = (FatSize * 512) * 2 / 3; iORDi, j;
PMRDp; iht}( 4
У)=С, j=0;i< Len; i+=2, j+=3){ ; • *(DW0RD*)(Faf + j); *Fat[il=pmfffff; >FalJi+1J = (p » 12) & Oxffffff;
im Len;
303
FatSize,
WORD
*wFat){
void FatPack (WORD *uFat, DWORD uFatSize BYTE 'Fat){ DWORD p; DWORD i; for (i = 0; i
}
}
BOOL FatWrite(DWORD FatAddr, DWORD FatSize BYTE'Fat DWORD S, DWORD H){ DWORD i.j; DWORD t, h, s, bool b; for (i=0, j = FatAddr; i
}
return true;
} К о р н е в о й к а т а л о г с о д е р ж и т т а б л и ц у файлов и КЕ в в е р ш и н е д е р е в а . Д л я к а ж д о г о ф а й л а з а д а е т с я его имя, атрк п а р а м е т р ы в р е м е н и , р а з м е р ф а й л а и н о м е р начального кл ( в е р ш и н а с п и с к а с н о м е р а м и к л а с т е р о в д л я файла). Структура каталога: struct ROOT{ BYTE Name[8]; // Короткое имя файла или первая часть BYTE Ext[3J; // Расширение BYTE Attr; //Атрибуты файла BYTE rsr1;//Резерв BYTE CreateTime[3]; //Время создания файла BYTE CteateDate[2]; //Дата создания файла BYTE LastAccessDate[2]; //Дата последнего доступа BYTE rsr2[2J; // Резерв BYTE LastChangeTime[2]; //Время последнего изменения BYTE LastChangeDate[2J; //Дата последнего изменения WORD ClustNumber; // Номер первого кластера (вершина DWORD FileSize;
}; 304
•
Функции
BOOL
для
чтения-записи
RootRead
(DWORD
корневого
каталога
RootAddr,
ROOT
*Root,
i
*32/512;
DWORD
RootSize,
DWORDS, DWORDH){ DWORD i, j; DWORD t, h, s;
boolb; RootAddr;
for (i=0, j =
i++,j++){
LAtoFAg h, t, s, H, S); b = ReadSector (0, h, t, s,
(BYTE*)Root);
if (!b) return false; (BYTE')Root
+=
512;
J
return true;
I BCOLRootWrite
(DWORD
DWORD S, DWORD DWORD i, j;
RootAddr,
ROOT
*Root,
DWORD
RootSize,
H){
DWORD f, h, s;
boolb; for (i=0, j = RootAddr,
i
* 32/512; /++, j++){
LAtoFA(j, h, t, s, H, S); b = WriteSector(0, h,
t, s,
(BYTE*)Root);
if(!b) return false; (BYTE')Rool += 512;
]
return true;
I
В сотчае задания длинного и м е н и о н о з а д а е т с я по ч а с т я м , ,гракаталога с длинным и м е н е м р а с с м о т р е н а н и ж е . В области данных р а с п о л о ж е н ы с а м и ф а й л ы и все к а т а л о г и , '•-некорневого каталога. Рассмотрим алгоритм о б р а щ е н и я к ф а й л у из к о р н е в о г о к а т а • на примере операции ч т е н и я . П р и р а с с м о т р е н и и а л г о р и т м а "читается, что системные о б л а с т и д и с к е т ы ( з а г р у з о ч н ы й ети таблица FAT и корневой к а т а л о г ) п р о ч и т а н ы в п а м я т ь . 1 Поиск файла по имени в к о р н е в о м к а т а л о г е ( л и н е й н ы й по№ Еста файл найден, определяются его р а з м е р (FileSize) и ног -ррвого кластера (ClustNumber), с к о т о р о г о н а ч и н а е т с я ф а й л , кластера определяет индекс в т а б л и ц е F A T . .'.Определение номера к л а с т е р а и с е к т о р а , с к о т о р о г о н а ч и яфайл (из формулы 7.1):
i
(DataSector—
ClustNumber
FirstDataSector)
SectorsPerCluster 305
+2
DataSector = ( ClustNumber—2) * SectorsPerCluster+FirstD • Sector; 3. По р а з м е р у ф а й л а о п р е д е л е н и е ч и с л а секторов и к.!—.:' в в файле, округленное в б о л ь ш у ю сторону: SectorsPerFile =
ClustersPerFile =
(File Size + BytesPerSector- 1) —; BytesPerSector (SectorsPerFile + SectorsPerCluster SectorsPerCluster
4. Д л я всех кластеров файла. Ч т е н и е к л а с т е р а , н а ч и н а я с с е к т о р а с номером
1)
.
DataSec'"
ClustNumber = Fat[ClustNumber] if (ClustNumber == OxFFF) break; DataSector = ( ClustNumber — 2) * SectorsPerCluster + FirstDataixn 5. П р о в е р к а с о о т в е т с т в и я р а з м е р а с п и с к а в таблице А количества кластеров д л я файла. Е с л и ф а й л не в к о р н е в о м к а т а л о г е , с а м каталог должен Ml п р е д в а р и т е л ь н о п р о ч и т а н . Д л я э т о г о в корневом каталоге и д и м п е р в у ю ч а с т ь т р е б у е м о г о п о д к а т а л о г а , определяем номе" v с т е р а , где он р а с п о л о ж е н , и ч и т а е м его к а к обычный файл Р а с с м о т р и м р а з л о ж е н и е на у р о в н и на примере фай тов.. J стемы типа FAT. Л о г и ч е с к а я о р г а н и з а ц и я . П о и м е н и файла опредеч у с т р о й с т в о , на к о т о р о м р а с п о л о ж е н ф а й л , и компоненты ии « и с п о л ь з у е м ы е д л я п о и с к а п о д е р е в у к а т а л о г о в . Предполо п р о с т о т ы , ч т о ф а й л р а с п о л о ж е н в к о р н е в о м каталоге. П о и с к по к а т а л о г у . Т а к к а к ф а й л находится в кор • к а т а л о г е , в ы п о л н я е т с я е г о п о и с к по и м е н и в корневом BOOT. О п р е д е л я е т с я н о м е р к л а с т е р а , в котором находится Е.И» файла. Б а з о в а я ф а й л о в а я с и с т е м а . По а т р и б у т а м файла опре"1" я ся в о з м о ж н о с т ь в ы п о л н е н и я н е о б х о д и м о й операции. Еслиосф ц и я д о п у с т и м а , то ч и т а е т с я ц е п о ч к а кластеров, которые за файл. Ф и з и ч е с к а я о р г а н и з а ц и я . По н о м е р а м кластера вычис. ся адреса секторов на диске. П л а н и р о в а н и е и у п р а в л е н и е вводом-выводом. Выполаато прямой доступ к диску д л я заданной операции. 306
Особенности F A T 1 6
Размер элемента таблицы FAT в случае F A T 16 р а в е н 16 бит, ' к максимальное количество э л е м е н т о в этой т а б л и ц ы р а в н о : Определим максимальный р а з м е р р а з д е л а с F A T 16, у ч и (иглм, что номер сектора задается 6 б и т а м и , т.е. м а к с и м а л ь н о е I «-пест секторов в кластере равно 2 е , и л и 64 с е к т о р а . Т а к к а к [•иартаый размер сектора равен 512 байт, то м а к с и м а л ь н ы й ркр кластера равен 32 Кбайта. В этом с л у ч а е м а к с и м а л ь н ы й раздела, который достигается п р и м а к с и м а л ь н о м р а з м е р е ia, равен 2s * 2 10 * 2 1 6 = 2 3 2 , и л и 4 Г б а й т а . Таким образом, F a t l 6 не обеспечивает в о з м о ж н о с т и р а б о т а т ь ! кьшими разделами, кроме того, д а ж е д л я р а з д е л а р а з м е р о м (Гбайтнеобходимо использовать к л а с т е р р а з м е р о м 32 К б а й т а , приводит к большим потерям д и с к о в о г о п р о с т р а н с т в а п р и •таи большого числа м а л е н ь к и х ф а й л о в . Вот п о ч е м у эта ФС современных винчестеров п р а к т и ч е с к и не и с п о л ь з у е т с я . Особенности FAT32
Загрузочная область занимает не о д и н , а т р и с е к т о р а . На имеется копия загрузочной области ввиду ее в а ж н о с т и , что швает надежность FAT32 по с р а в н е н и ю с F A T 1 6 . Размер элемента таблицы FAT — 32 бита, из к о т о р ы х 28 бит - „гея для номера кластера, поэтому д а ж е п р и р а з м е р е к л а с т е . лнеектор, размер раздела с F A T 3 2 р а в е н 2 2 8 * 2 9 = 2 3 7 байтов, ь28 Гбайт. Так как размер кластера обычно не менее 4 К б а й т реграницы), то размер раздела 2 4 0 , и л и 1 Тбайт. Д в е т а б л и . FAT не обязательно должны совпадать, есть в о з м о ж н о с т ь отВ чть режим зеркального отображения с о д е р ж и м о г о т а б л и ц ; • случае задается активная таблица FAT, Тогда м о ж н о с к р ы т ь |рыекаталоги и файлы при п е р е к л ю ч е н и и т а б л и ц F A T . Корневой каталог рассматривается к а к о б ы ч н ы й ф а й л , пог его размеры не ограничены, к а к это было д л я п р е д ы д у щ и х ла FAT. Это дает возможность у в е л и ч и т ь к о л и ч е с т в о элевкорневого каталога, что особенно в а ж н о п р и и с п о л ь з о в а ггтиввых имен, требующих более одной з а п и с и в к а т а л о г е . Недостатки FAT32. 1. Элементы в каталог з а п и с ы в а ю т с я в п о р я д к е с о з д а н и я [тов этого каталога, поэтому поиск н е о б х о д и м ы х э л е м е н т о в ' чгапри большом числе элементов м е д л е н н ы й . с. Размер цепочки в таблице FAT о п р е д е л я е т с я р а з м е р о м (tfan не зависит от его фрагментации. Д л я б о л ь ш и х ф а й л о в эта 307
ц е п о ч к а д л и н н а я , п о э т о м у в р е м я д о с т у п а к з а п и с я м файла в е л о даже для нефригментированных файлов. 3 . П о и с к п у с т о г о м е с т а н а д и с к е в ы п о л н я е т с я с помог** п р о с м о т р а т а б л и ц ы F A T , н е т о б о б щ е н н о й и н ф о р м а ц и и о свобог еой части диска. 4 . Ф С н е и м е е т с р е д с т в з а щ и т ы , т а к к а к д л я ф а й л а вевозхо» но определить права доступа.
|
5- ФС не з а щ и щ е н а от сбоев. 8.7.3. Ф а й л о в а я с и с т е м а NTFS К а к с л е д у е т и з а н а л и з а в с е х ф а й л о в ы х с и с т е м типа FAT. и х о б щ и м и н е д о с т а т к а м и я в л я ю т с я : о т с у т с т в и е защищенное?! ф а й л о в и в о с с т а н а в л и в а е м о с т и ф а й л о в о й с и с т е м ы ; использовал: б о л ь ш и х р а з д е л о в и л и н е д о п у с к а е т с я ( F A T 16), и л и веэффектип> в в и д у л и н е й н о г о п о и с к а ф а й л о в в к а т а л о г а х . В с е э т и ведосташ | у ч т е н ы п р и р а з р а б о т к е N T F S ( N e w T e c h n o l o g y F i l e System!. Основные преимущества NTFS Н и ж е п р е д с т а в л е н ы о с н о в н ы е п р е и м у щ е с т в а NTFS по срагнению с файловыми системами типа FAT. 1 . N T F S я в л я е т с я в о с с т а н а в л и в а е м о й ФС- Пользователя р е к о п р и х о д и т с я п р и м е н я т ь п р о г р а м м ы д л я восстановления днем N T F S г а р а н т и р у е т ц е л о с т н о с т ь т о м а з а с ч е т испольэовавня m i | д а р т о в т р а н з а к ц и и и т е х н о л о г и и в о с с т а н о в л е н и я . Все опере дм. к о т о р ы е в ы п о л н я е т N T F S , п р о т о к о л и р у ю т с я . В случае сшнбвв. N T F S и с п о л ь з у е т ф а й л ж у р н а л а д л я а в т о м а т и ч е с к о г о восстаю л е н и я ц е л о с т н о с т и ф а й л о в о й с и с т е м ы з а с ч е т о т к а т а д л я тех г а раций, которые завершились неблагополучно. 2 . N T F S н е о г р а н и ч и в а е т к о л и ч е с т в о э л е м е н т о в корнем к а т а л о г а Ф С . К о р н е в о й к а т а л о г я в л я е т с я о б ы ч н ы м файлом, D э т о м у р а з м е р ы е г о н е о г р а н и ч и в а ю т с я ( к а к в F A T 1 2 . FAT16J. 3 . П о д д е р ж и в а е т р а з д е л ы д о 2 Т б а й т . П о д н о м е р кластер» о т в о д и т с я 6 4 б и т а , п о э т о м у д а ж е д л я к л а с т е р а размером I сеттер р а з м е р раздели 20Э К б а й т > 2 4 1 б а й т . 4 . N T F S у п р а в л я е т д и с к о в ы м п р о с т р а н с т в о м более эффектын о , ч е м в с е F A T , и с п о л ь з у я м е н ь ш и е к л а с т е р ы ( 4 Кбайт для том р а з м е р о м д о 2 Т б а й т ) . д л я F A T 3 2 м а к с и м а л ь н ы й диск 3 2 ГбаДт п р и э т о м р а з м е р к л а с т е р а 4 К б а й т а м а к с и м у м д л я 8 Гбайт длено». 5 . Т а к ж е , к а к д л я F A T 3 2 , х р а н и т с я к о п и я boat-сектора, f t ) з а п и с ы в а е т с я о н а не в н а ч а л е , а в к о н ц е т о м а , ч т о увеличивает 308
пность е е с о х р а н н о с т и в с л у ч а е ф и з и ч е с к о г о п о в р е ж д е н и я
кдиска. 6. NTFS минимизирует число доступов к д и с к у при обращецфайлу за счет использования M a s t e r File Table и Ь-деревьев I ниже). Master File Table (MFT) — с и с т е м н а я таблица, хра»я информацию о файлах. Д л я поиска ф а й л а в каталоге исдаяЬ-дерево, что более эффективно, чем л и н е й н ы й поиск, темый в ФС FAT. 7 Можно ограничить доступ к п а п к е , ф а й л у д л я г р у п п ы и гальных пользователей. Ограничения у с т а н а в л и в а ю т с я д л я i; в и папок на локальной и сетевой м а ш и н а х . Т а к и е ограничеИподдерживает ни одна из ФС типа FAT. 8 NTFS поддерживает так называемые с ж а т ы е тома, когда ование файлов и папок в ы п о л н я е т с я прозрачно д л я поль;гля, при чтении файла любым п р и л о ж е н и е м он автоматичерхивируется, при записи его на диск — а р х и в и р у е т с я . 9. NTFS поддерживает использование систем ш и ф р о в а н и я , .^t File System, которая использует к о м б и н а ц и ю алгоритмов •втричного и несимметричного ш и ф р о в а н и я . Ш и ф р о в а н и е и рованпе выполняются прозрачно д л я санкционированноювателя. 10. Каждому пользователю м о ж е т быть определена д и с к о в а я т.е. максимальный размер дискового пространства. И. Для задания имен файлов и каталогов используется UNIЕ, в этом случае нет ограничений на использование р а з л и ч I -зыков для задания имен файлов. 12. Можно задать режим совместимости с POSIX (регистроельные имена; метки времени, использование множества ЮКНА один файл и специальных потоков внутри файла). Недостатки NTFS Ниже рассмотрены н е к о т о р ы е н е д о с т а т к и
NTFS.
1. NTFS-тома не видимы операционными системами MS-DOS, D0WS 95, или WINDOWS 98. Некоторые особенности недоj даже младшим версиям W I N D O W S N T . 2.Для маленьких томов, с о д е р ж а щ и х б о л ь ш о е ч и с л о м а VXфайлов, NTFS может быть медленнее, чем F A T .
x
Структура тома с N T F S
Для задания номера кластера в N T F S используется 64 бита, j-'лудаже для кластера длиной 1 сектор с размером 512 байт 309
п о л у ч а е м р а з м е р р а з д е л а 2 С З К б а й т , ч т о соответствует соврем» н ы м и п е р с п е к т и в н ы м в н е ш н и м устройствам. Д л я уменьшав! ф р а г м е н т а ц и и ф а й л о в и у с к о р е н и я доступа к большим фяйли в ы б и р а е т с я р а з м е р к л а с т е р а б о л ь ш е , ч е м о д н а сектор. У т а я т FORMA Т в ы б и р а е т р а з м е р к л а с т е р а в зависимости от размера дт к а , н о этот р а з м е р м о ж е т быть з а д а н непосредственно. Д л я о п р е д е л е н и я ф и з и ч е с к о г о места на д и с к е NTFS ист > | з у е т п о н я т и е номера л о г и ч е с к о г о к л а с т е р а (Logical Cluster \ u a b e r — LCN). LCN — э т о н о м е р к л а с т е р а п р и сквозной нумер* цо к л а с т е р о в , н а ч и н а я с О. Д л я о п р е д е л е н и я смещения в байтах соответствующего LCN. н е о б х о д и м о LCN у м н о ж и т ь нв размер ки стера в байтах. Д л я о п р е д е л е н и я ф и з и ч е с к о г о р а с п о л о ж е н и я частей фа4» I не д и с к е и с п о л ь з у е т о я п о н я т и е н о м е р а виртуального клеем* I ( V i r t u a l C l u s t e r N u m b e r — VCN). К л а с т е р ы , которые отводяд л я ф а й л а , н у м е р у ю т с я , н а ч и н а я с 0. VCN — вомер класт в ф а й л е п р и т а к о й с к в о з н о й н у м е р а ц и и . В этом случае, в е з ш и мо от ф р а г м е н т и ц и и ф а й л а на д и с к е , его виртуи чьные кластер! всегда п р о н у м е р о в а н ы п о д р я д . И н ф о р м а ц и я о ф а й л е з а д а е т с я в в и д е таблицы, количеств строк к о т о р о й о п р е д е л я е т с я ч и с л о м фрагментов фай та яв дш»< | Д л я к а ж д о г о ф р а г м е н т а з а д а ю т с я н а ч в л ь и ь ш логический яов*р кластера (LCN), н а ч а л ь н ы й в и р т у а л ь н ы й номер (VCN) и кс m ство к л а с т е р о в . П р и м е р . П у с т ь ф а й л состоит из 10 кластеров, 15-23,29. Зге ф а й л имеет 2 ф р а г м е н т а , п о э т о м у в т а б л и ц е размещения ф*Ьг получим 2 строки: 1 с т р о к а — LCN 15; VCN = 0; Count = 9 2 с т р о к а - LCN = 2 9 ; VCN = 9; Count = 1 З а м е т и м , что последнее поле т а б л и ц ы можно ве задавать, DID получается к а к : Count,
VCN,
!
VCN,,
где: VCNi + i — в и р т у а л ь н ы й н о м е р к л а с т е р а д л я строки i*l: VCN, в и р т у а л ь н ы й н о м е р к л а с т е р а д л я строки i; Count.1 — к о л и ч е с т в о к л а с т е р о в д л я строки i. Т е м не менее, это поле з а д а е т с я , ч т о позволяет иногда существенно с э к о н о м и т ь д и с к о в о е п р о с т р а н с т в о (см. задание Span; файлов). Т а к и м образом, к о л и ч е с т в о с т р о к д л я задания флйтв в е я висит от его р а з м е р а и о п р е д е л я е т с я т о л ь к о числом фрагмента 310
I
k!ia. Большие системные ф а й л ы , к а к п р а в и л о , н е ф р а г м е н т и р о мшдля и х задания д о с т а т о ч н о о д н о й с т р о к и . Д л я о п р е д е л е н и я **ческого расположения н а ч а л а ф а й л а д о с т а т о ч н о LCN п е р в о й i-шственной) строки у м н о ж и т ь н а р а з м е р к л а с т е р а . Сравним этот способ а д р е с а ц и и с а д р е с а ц и е й д а н н ы х д л я Щшв с файловой с и с т е м о й т и п а F A T . Д л я з а д а н и я в F A T п о лется 1 0 записей д л я э т о г о ф а й л а в м е с т о д в у х в N T F S , п р и ч е м оличество зависит т о л ь к о о т р а з м е р а ф а й л а и н е з а в и с и т о т • Фрагментации. Д л я о п р е д е л е н и я ф и з и ч е с к о г о р а с п о л о ж е н и я | ила файла необходимо з н а т ь а д р е с н а ч а л а р а з д е л а д а н н ы х на ( е. В NTFS все разделы д и с к а , в т о м ч и с л е и с и с т е м н ы е , н а з ы в а я файлами. П о с л е д н и е и н о г д а н а з ы в а ю т с я м е т а д а н н ы м и i -e NTFS metadata). В этом с л у ч а е д р а й в е р ф а й л о в о й с и с т е м ы таково работает к а к с с и с т е м н ы м и с т р у к т у р а м и , т а к и с о б ы ч iu< файлами. Сердцем Ф С я в л я е т с я т а б л и ц а ф а й л о в ( M a s t e r В Me — MFT). В этой т а б л и ц е к а ж д о м у ф а й л у о т в о д и т с я "строка. Первые 16 с т р о к о т в о д я т с я с и с т е м н ы м р а з д е л а м , в м числе самой MFT. Д л я э т и х р а з д е л о в и м е н а ф а й л о в н а ч и н а 1 с символ а $, который з а п р е щ е н в к а ч е с т в е с и м в о л а о б ы ч н о г о f r r i a . Так, имя файла д л я M F T : $ M f t . Н е з а в и с и м о о т р а з м е р а гра, размер строки M F T 1 К б а й т 1 . Для понимания а л г о р и т м а д о с т у п а к ф а й л у р а с с м о т р и м |г-1ввые системные р а з д е л ы . Строка0. $Mft — MFT — с т р о к а д л я т а б л и ц ы . Строка 1. $MftMirr — к о п и я п е р в ы х 3 - х с т р о к M F T . И с п о л ь ijr.i, если при чтении о с н о в н о й т а б л и ц ы о б н а р у ж е н а о ш и б к а . «таблицы расположены н а д и с к е н е п о д р я д д л я у в е л и ч е н и я «мвости при повреждении ч а с т и д и с к а . Строка 2. $LogFile — ф а й л ж у р н а л а , к у д а з а н о с и т с я и н ициация обо всех и з м е н е н и я х д и с к а , п о з в о л я е т в о с с т а н о в и т ь Шость ФС при з а г р у з к е в с л у ч а е н е б л а г о п о л у ч н о г о з а в е р ш е Вшдыдущего сеанса р а б о т ы с ОС. Строка 3. $Volume — и н ф о р м а ц и я о р а з д е л е д и с к а с N T F S - объем). Строка 4. $AttrDef — т а б л и ц а а т р и б у т о в , б у д е т р а с с м о т р е н а
1
т. лныв ралмер выбран фирмой Microsoft на основании статистических исслеnii. Hs что влияет этот размер, вы поймете ниже. Пока ясно, что чем больше «• издар, тем больше места должно быть выделено на диске для таблицы при •к I гом же количестве файлов. 311
С т р о к а 5. \ — к о р н е в о й к а т а л о г . С т р о к а 6- $Bitmap — д в о и ч н а я к а р т а з а н я т ы х и свой л я . к л а с т е р о в . Ч т о б ы н а й т и с в о б о д н ы й к л а с т е р , п е требуется пропш т р н в а т ь т а б л и ц у F A T . д о с т а т о ч н о п р о а н а л и з и р о в а т ь Bitmap. С т р о к а 7. SBoot - з а г р у з о ч н а я о б л а с т ь , в н е й н а х о д и т I fг р в м м а н а ч а л ь н о й з а г р у з к и , к о т о р а я з а г р у ж а е т программу Ш * е х е и з к о р н е в о г о к а т а л о г а д и с к а ( о п р е д е л е н в с т р о к е 5). С т р о к а 8. $BadClus — и н ф о р м а ц и и о п л о х и х кластера!. И* кластеры не используются при з а п и с и новых файлов. С т р о к а 9. SSecure — п а р а м е т р ы б е з о п а с н о с т и , принятием умолчанию, относящиеся ко всему разделу. С т р о к а 1 0 . $Upcase — т а б л и ц а п р е о б р а з о в а н и я кодов мал к и х б у к в в з а г л а в н ы е . Ф С п о у м о л ч а н и ю и с п о л ь з у е т регистре * в а в и с и м ы е и м е н а ф а й л о в . П о э т о м у п р и х о д и т с я переводить RMUL з а д а н н ы е м а л е н ь к и м и б у к в а м и , в б о л ь ш и е . Е с л и тнблпна пер«в д а я в л я е т с я в н у т р е н н е й ч а с т ь ю п р о г р а м м ы , т о потребуется « * н я т ь э т у п р о г р а м м у п р и и з м е н е н и и в т а б л и ц е . В последнем < f л » достаточно т о л ь к о и з м е н и т ь и л и д о п о л н и т ь этот файл. С т р о к а 1 1 . $Extend — ф а й л д л я р а с ш и р е н и я особенно-л файловой системы. С т р о к и 12 15 - з а р е з е р в и р о в а н ы . П о с л е 1 6 с т р о к и о б ы ч н о р а с п о л а г а ю т с я ф а й л ы , onpej? щ и е д о п о л н и т е л ь н ы е в о з м о ж н о с т и N T F S , т а к и е к а к квота. a r j вирование и т.д.. зятем строки д л я о б ы ч н ы х файлов. К а ж д о м у ф а й л у с т а в и т с я в с о о т в е т с т в и е 64-битное чнс г т о р о е н а з ы в а е т с я н о м е р о м ф а й л а (File Reference Number FRf Э т о т н о м е р о п р е д е л я е т : н о м е р с т р о к и в M F T . г д е определен жгф а й л ( 4 8 м л а д ш и х р а з р я д о в ) , и с ч е т ч и к с с ы л о к ( 1 6 старших p t р я д о в ) . Т а к и м о б р а з о м , ф у н к ц и я м п о и с к а з а д а е т с я п е ими фв1л, к а к в F A T , a FRN, ч т о з н а ч и т е л ь н о у с к о р я е т п о и с к . Р а с с м о т р и м о с о б е н н о с т и з а д а н и я ф а й л а в M F T , т.е. стр)*п ру строки MFTК а ж д ы й ф а й л з а д а е т с я м н о ж е с т в о м е г о с в о й с т в (втрн' - г С п и с о к и м е н в с е х в о з м о ж н ы х а т р и б у т о в д л я ф а й л а опрез-^ез в с т р о к е 4 M F T . К а ж д ы й а т р и б у т з а д а е т с я в в и д е : И м я птрвб' т. Значение (как ключевой параметр к л ю ч и его значение). Ben о д и н а т р и б у т б е з и м е н и — э т о д п н н ы е ф а й л а . Т а к к а к дашш м о ж н о з а д а в а т ь не т о л ь к о с п о м о щ ь ю б е з ы м я н н о г о атрибута во • с п о м о щ ь ю и м е н н ы х , то е с т ь в о з м о ж н о с т ь з а д а т ь несколько поток о в д а н н ы х в о д н о м ф а й л е . С р е д и а т р и б у т о в е с т ь обязательны!: н е о б я з а т е л ь н ы е . О б я з а т е л ь н ы й а т р и б у т з а д а е т с я в начале строш 312
f в называется $STANDARTJNFORMA TION.
Этот а т р и б у т за-
- атрибуты файла, такие к а к : т о л ь к о д л я ч т е н и я , с к р ы т ы й , квый,...; -метки времени ( с о з д а н и я , п о с л е д н е г о д о с т у п а и м о д и ф и \ -количество файлов, к о т о р ы е п р и к р е п л е н ы к э т о м у ф а й л у Link). Имя файла задается с п о м о щ ь ю а т р и б у т а $F1LE NAME. Э т о д а е т с я в UNICODE. Е с л и ф а й л и м е е т ж е с т к и е с в я з и , з д е с ь ются имена всех с в я з е й с т е м же и м е н е м а т р и б у т а . Е с л и юму имени ставится в с о о т в е т с т в и е к о р о т к о е и м я , о н о з а я тут же. Данные файла з а д а ю т с я с п о м о щ ь ю а т р и б у т а $DATA. И м я г ё у т а о п у щ е н о для первого ( е д и н с т в е н н о г о ) п о т о к а д а н н ы х . [ Прежде чем р а с с м а т р и в а т ь д р у г и е а т р и б у т ы , р а с с м о т р и м р задания файла с о д н и м п о т о к о м , д а н н ы е к о т о р о г о п о м е тя в одной строке M F T . В э т о й с т р о к е з а д а ю т с я п о л я : - SSTANDARTJNFORMA TION; -^FILENAME;
-Данные файла. Для обращения к т а к о м у ф а й л у д о с т а т о ч н о п р о ч е с т ь о д н у у таблицы MFT. Если файл большой и его а т р и б у т ы не п о м е щ а ю т с я в с т р о к е , •> первой строке MFT з а д а е т с я с п и с о к а т р и б у т о в со с с ы л к о й на я, где он задан, т а к о й с п и с о к з а д а е т с я с п о м о щ ь ю а т р и б у lUTlRIBUTEJ.IST. В э т о м с л у ч а е а т р и б у т ы м о ж н о р а з д е л и т ь I [езидентные, заданные в 1 - о й с т р о к е M F T д л я ф а й л а , и н е д а я н ы е , н а которые с с ы л а е т с я с п и с о к а т р и б у т о в . Р а з м е р «в MFT определяет н а л и ч и е и л и о т с у т с т в и е н е р е з и д е н т н ы х в. Поле $STANDARTJNFORMATION в с е г д а р е з и д е н т н о ! Для файлов с н е р е з и д е н т н ы м з а д а н и е м д а н н ы х о п р е д е л я е т с я ца размещения ф а й л а ( L C N , V C N ) . Н а п о м и н а е м , ч т о р а з м е р i т а б л и ц ы зависит о т ч и с л а ф р а г м е н т о в ф а й л а и н е з а в и с и т о т |
Рассмотрим особенности з а д а н и я к а т а л о г о в . СтрокаMFT для к а т а л о г а , с о д е р ж а щ е г о 4 ф а й л а , и м е е т в и д : - $SmNDARTJNFORMA TION; - $FILE_NAME; -mDEX ROOT (IndexfOJ, Index [1], Index [2], Index [3]);
-He используется. 313
П о с л е з а д а в и я с т а н д а р т н о й и н ф о р м а ц и и {SSTANDART INFORMATION) и и м е н и к а т а л о г а ($FILE_NAME) задаются нндга с ы ф а й л о в ( $ I N D E X _ R O O T ) . И н д е к с ф а й л а в к л ю ч а е т в себя егоям» и 64-битный номер файла (RFN). Е с л и и н ф о р м а ц и я о ф а й л а х не п о м е щ а е т с я в одной запаса с о з д а ю т с я д о п о л н и т е л ь н ы е з а п и с и , р е з и д е н т н ы м и ставовятм н о м е р а э т и х з а п и с е й , я о н и у ж е с о д е р ж а т н о м е р а файлов, вхслл щ и х в э т и з а п и с и . Д л я ф а й л а м о ж н о з а д а т ь н е т о л ь к о нндекш но и к а р т у р а с п о л о ж е н и я ф а й л а с б о л ь ш и м к а т а л о г о м — атрн$INDEX_ REFERENCE. В э т о м с л у ч а е и с п о л ь з у е т с я таблица с отв е т с т в и я LCN п VCN ( с м . в ы ш е ) . П р и к л а с т е р е р а з м е р о м 4 KCif в нем могут содержаться и н д е к с ы д л я 2 0 - 3 0 файлов. П р и с о з д а н и и к а т а л о г а о н с р а з у у п о р я д о ч и в а е т с я (строит ся с б а л а н с и р о в а н н о е fc-дерено). В э т о м д е р е в е к о р н е м являе и к о р н е в о й к а т а л о г , в е т в я м и — в л о ж е н н ы е к а т а л о г и , листьями файлы. К а ж д ы й ф а й л р а с с м а т р и в а е т с я Ф С к а к о б ъ е к т , которо» Ф С п р и с в а и в а е т у н и к а л ь н ы й н о м е р — и д е н т и ф и к а т о р объект! И д е н т и ф и к а т о р о б ъ е к т а — 6 4 - б а й т и о е ч и с л о . П е р в ы е 16 байт у н и к а л ь н ы д л я у с т р о й с т в а , п о э т о м у г а р а н т и р у е т с я уникальность э т о г о и м е н и д л я р а з л и ч н ы х у с т р о й с т в . Ф у и к ц и и Win Apt работает б ы с т р е е с и д е н т и ф и к а т о р о м о б ъ е к т а , ч е м с и м е н е м файла. Есп ф у н к ц и и , к о т о р ы е п о з в о л я ю т у с т а н о в и т ь соответствие ые*и НИМИ. Д л я з а д а н и я и д е н т и ф и к а т о р а о б ъ е к т а ИСпольяуется arpi б у т SOBJECT ID. Н е д о с т а т о к т а к и х ф у н к ц и й — работают толи с ф а й л а м и на д и с к е с N T F S . И д е н т и ф и к а т о р ы в с е х объектов * п и с ы в а ю т г я в с п е ц и а л ь н ы й ф а й л в в и д е fc-дерева. поэтому по среди идентификаторов в ы п о л н я е т с я быстро. Обзор дополнительных возможностей для NTFS Д л я о п р е д е л е н и я д о п о л н и т е л ь н ы х в о з м о ж н о с т е й файловых систем
используется
функция
GelVolumelnformelion ( с л . 8.8);
Пример использования функции Ч char RootPalhNamefl = "С.1Г; char VolumeNameBuffer[80]: char FileSyslemNameBufferf80]; DWORD dwVolumeSenelNumber; DWORD dwMaximumCcmponentLength; DWORD dwFileSyslemFlags. 1
Исследуется диск С. 314
b = GetVolumelnformation(RootPathName, VolumeNameBuffer, sizeof (VolumeNameBuffer), &dwVolumeSerialNumber, &dwMaximumComponentLength, &dwFileSystemFlags, FileSystemNameBuffer, sizeof (FileSystemNameBuffer)); Регистровая чувствительность имени файла mFileSystemFlags & FS_CASE_SENSITIVE)
I
printf (FSCA SE_ SEN SI Tl VE: YES \n"); if (dwFileSystemFlags & FS_CASEJS PRESERVED) printf (TS CASEJS_ PRESERVED:YES I n");
I --fee printf (FS_CASE_SENSITIVE:NO\n"); Wcпользование UNICODE для имени файла tfduFifeSystemFlags & FS_CASE_ SENSITIVE) printf (TS_UNICODE_STORED__ON_DISK:YES\n"); else printf ("FS_UNICODE_STORED_ON_DISK:NO\n"); "Использование списков доступа ACL illdwFileSystemFlags & FS_CASE_SENSITIVE) f Pmlff FS_PERSISTENT_ACLS:YES\n");
I Be
printf ("FS_PERSISTENT_ACLS:NO\n"); Ь Использование разреженных файлов HfdwFileSystemFlags & FILE_SUPPORTS_SPARSE_FILES) printf ("FILE_ SUPP OR TS_ SPARSE_FILES:YES\n"); •fee ntf("FILE_SUPPORTS SPARSE_FILES:NO\n"); iИспользование сжатых файлов и проверка, является ли ткущий диск сжатым ttdwFifeSystemFlags & FS_FILE_COMPRESSION) printf (FSFILECOMPRESSION:YES\n"); if (dwFileSystemFlags & FS_VOLJS_COMPRESSED) printf (:FS_VOLJS_COM PRESSED :YES\n"); else printf (TS_ VOL IS COMPRESSED:NO\n"); 315
I
else printf ("FS_FILE_COMPRESSION. NOW); // Использование шифрования if (dwFileSystemFlags & FILE_SUPPORTS_ENCRYPTION) { ENCRYPTiON:YES\nn);
printf (FILE_SUPPORTS
}
else printf
("FILE_SUPPORTS_ENCRYPTION:NO\n");
//Использование дисковых квот if (dwFileSystemFlags & FILE_VOLUME_QUOTAS) { printf
("FILE_VOLUME_QUOTAS:YES\n");
printf
("FILE_VOLUME_QUOTAS:NO\n");
}
else
} Sporse-файлы Т а к н а з ы в а ю т р а з р е ж е н н ы е ф а й л ы , т . е . ф а й л ы , болыпинсги) элементов которых равно 0. Е с л и ф а й л б о л ь ш о й , он з а н и м а е т б о л е е одного кластера. В si и с л у ч а е д л я ф а й л а з а д а е т с я т а б л и ц а с о о т в е т с т в и я логического и ви] т у а л ь н о г о к л а с т е р о в . П р и м е р т а б л и ц ы с о о т в е т с т в и я (табл. 8.1): Таблицав 1 Таблица распределения дискового п р о с т р а н с т в а д л я обычного ф а й л а Номер фрагмента
Номер логического кластера (LCN)
Номер виртуального кластера (VCN)
Число кластеров
1
1000
0
4
2
1200
4
4
3
1500
8
4
В э т о й т а б л и ц е о п р е д е л е н а и н ф о р м а ц и я о ф а й л е , в которой 1 2 к л а с т е р о в , 3 ф р а г м е н т а . П у с т ь э т о т ф а й л з а д а н к а к разреже! н ы й ф а й л . В э т о м с л у ч а е п р и з а п и с и о ч е р е д н о г о кластера провер я е т с я , е с т ь л и в н е м н е н у л е в ы е э л е м е н т ы . Е с л и т а к и х элементов н е т , т о д а н н ы й к л а с т е р н а д и с к н е з а п и с ы в а е т с я , логически к л а с т е р ы е м у н е в ы д е л я ю т с я . П у с т ь в э т о м ф а й л е нулевыми являю т с я п е р в ы е 6 к л а с т е р о в . Т о г д а т а б л и ц а р а с п р е д е л е н и я днековог пространства будет и м е т ь вид: 316
Таблица
8.2
Таблица распределения дискового пространства для Sparse-файла с нулевым вторым фрагментом -чер Г. Г' КеЕТЕ
Номер логического кластера (LCN)
Номер виртуального кластера (VC/V)
Число кластеров
1
1000
6
4
2
1500
10
2
Для этого файла п о т р е б у е т с я т о л ь к о 2 ф р а г м е н т а , о д и н из В'"гдат свободным. Н а л и ч и е н у л е в о г о ф р а г м е н т а м о ж е т б ы т ь т а е н о п о значению н о м е р а в и р т у а л ь н о г о к л а с т е р а . П р и ч т е • такого файла ОС о б н а р у ж и в а е т « п р о п у с к и » и з а п о л н я е т их амяти нулями. Сжатие файлов и п а п о к
Для увеличения э ф ф е к т и в н о с т и и с п о л ь з о в а н и я д и с к о в о г о йранства, наряду с и с п о л ь з о в а н и е м S p a r s e - ф а й л о в , N T F S п о д гнивает сжатие и н д и в и д у а л ь н ы х ф а й л о в , п а п о к и т о м о в N T F S . •rueфайлы н а томе N T F S м о г у т б ы т ь п р о ч и т а н ы и л и з а п и с а н ы печно для приложений. Р а с п а к о в к а и х в ы п о л н я е т с я а в т о м а Ггки, когда файл ч и т а е т с я . Ф а й л у п а к о в ы в а е т с я с н о в а , к о г д а лняется. Когда п р и л о ж е н и е т и п а M i c r o s o f t W o r d и л и к о м а н С, например, сору, в ы п о л н я е т з а п р о с к ф а й л у , д р а й в е р , п р е д •иерныйдля работы с т а к и м и ф а й л а м и , р а с п а к о в ы в а е т ф а й л "обеспечением доступа к н е м у . К п р и м е р у , е с л и к о п и р у е т с я I ий файл, он р а с п а к о в ы в а е т с я , к о п и р у е т с я , а з а т е м с н о в а йпвывается, если у с т р о й с т в о п о д д е р ж и в а е т р а б о т у с о с ж а т ы м и •ими. Это обеспечивает в о з м о ж н о с т ь б е с п р е п я т с т в е н н о г о о б IE. -иными. Сжатие в N T F S м о ж е т и с п о л ь з о в а т ь с я т о л ь к о д л я -еров меньше 4 Кбайт. Е с л и р а з м е р к л а с т е р а б о л ь ш е 4 К б а й т , Кмтиеинформации н е в ы п о л н я е т с я . П р и к о п и р о в а н и и с ж а т о Iftfcia в папку, отмеченную к а к н е с ж а т а я , ф а й л с н а ч а л а р а з а р Ш'руется, а затем к о п и р у е т с я . Е с л и ф а й л к о п и р у е т с я в п а п к у , Потной уже есть такой ф а й л , о п р е д е л я е т с я а т р и б у т э т о г о ф а й л а I мыл файл записывается в с о о т в е т с т в и и с э т и м и а т р и б у т а м и dura зрения сжатости. Р а с с м о т р и м о с о б е н н о с т и к о п и р о в а н и я Ю переименования ф а й л о в м е ж д у р а з л и ч н ы м и ф а й л о в ы м и 'чами, в том числе, е с л и о д н а и з ф а й л о в ы х с и с т е м н е п о д превает использования с ж а т ы х ф а й л о в . Е с л и ц е л е в о й д и с к к задерживает работы с о с ж а т ы м и ф а й л а м и , о н и с н а ч а л а р а з >уются, а затем к о п и р у ю т с я . П о э т о м у п о с л е к о п и р о в а н и я 317
и л и п е р е и м е н о в а н и я д о с т у п к т а к о м у ф а й л у нормальный Бел д и с к с N T F S п р а к т и ч е с к и п о л н ы й , а д л я д о с т у п а к файлу TpeV ется его р а з а р х и в и р о в а н и е и места д л я полного файла не шп ф о р м и р у е т с я о ш и б к а п о ч т е н и ю ф а й л а - З а м е т и м , что к а ж ш ! п о т о к д а н н ы х д л я ф н й л а и м е е т с в о й а т р и б у т архивирования, t 1 о д и н п о т о к м о ж е т б ы т ь с ж а т , д р у г о й — н е т . Б о л е е того, ножи б ы т ь с ж а т а ч а с т ь п о т о к а . Т а к а я ч а с т ь п о т о к а отмечается мепо1 « h o l e s * . П р и с ч и т ы в а н и и м е т к и с о о т в е т с т в у ю щ и е данные jtasа р х и в и р у ю т с я . П р и з а п и с и э т о й ч а с т и в ы п о л н я е т с я обрати! о п е р а ц и я . Обе о п е р а ц и и в ы п о л н я ю т с я п р о з р а ч н о для upie ж е н и я . Т а к к а к п р и и с п о л ь з о в а н и и ф а й л д о л ж е н быть ра«мг» а п е р е д з а п и с ь ю с н о в а с ж а т , о ч е н ь с т р о г и е т р е б о в а н и я преды» л я ю т с я к с к о р о с т н ы м х а р а к т е р и с т и к а м а л г о р и т м а сжатие П и в ы б о р е а л г о р и т м а м о ж н о з а д а т ь к р и т е р и й д л я оптп.чн В к а ч е с т в е к р и т е р и е в и с п о л ь з у ю т с я с к о р о с т ь с ж а т и я и радо] данных после с ж е т и я . А л г о р и т м с ж а т и я . О с н о в н о е т р е б о в а н и е — скорость, т м и р а з ж а т и е д о л ж н о в ы п о л н я т ь с я « н а л е т у » . Ф а й л делится н и 6аы« д л и н о й 1 6 к л а с т е р о в . Е с л и р а з м е р ф а й л а м е н ь ш е 1 6 кластер» о н и е с ж и м а е т с я . Н е п о л н а я п о р ц и я н е с ж и м а е т с я . Очередные I I к л а с т е р о в ч и т а ю т с я в п а м я т ь . П р о в е р я е т с я возможность и х и з т и я ( м е т о д — о д и н а к о в ы е п о с л е д о в а т е л ь н ы е с и м в о л ы заменяй--» с и м в о л о м и ч и с л о м п о в т о р е н и й ) . Е с л и в е с ч е т с ж а т и я удмта у м е н ь ш и т ь р а з м е р х о т я б ы н а о д и н к л а с т е р , н а д и с к аалнгнию т с я с ж а т ы е д а н н ы е , в п р о т и в н о м с л у ч а е — нет. Корректируй« т а б л и ц а р а с п р е д е л е н и я д и с к о в о г о пространства. Пример и б и о для сжатого файла приведен в табл. 8.8. Таблица S Т а б л и ц а р а с п р е д е л е н и я дискового пространства д л я сжатого файл Номер фрагмента
Номер логического кластера (LCN)
Номер виртуального кластера СVCW)
Чигкласт«{Ш
1 2
1000
0
10
1010
16
4
1
И з т а б л и ц ы с л е д у е т , ч т о п е р в ы й б л о к р а з м е р о м 1 6 miacttf* б ы л у п а к о в а н д о р а з м е р а 1 0 к л а с т е р о в . В т о р о й блок рвммрв» 4 к л а с т е р а я в л я е т с я н е п о л н ы м , п о э т о м у и е упаковывается. Р а с с м о т р и м п р о г р а м м н о е у п р а в л е н и е р е ж и м о м сжатии файлов и папок П у с т ь н е о б х о д и м о ф п й л d a t a . t x t з а п и с а т ь в сжатом формя 318
риала необходимо п р о в е р и т ь , ч т о д а н н ы й р е ж и м п о д д е р е м . 8.7.3). )еделим дескриптор ф а й л а : % CreateFile ("data.txtGENERIC^ READ\GENERIC_WRITE, О, О, OPENEXISTING, О, 0); i(/i== imLID_HANDLE_VALUE) printf ("CreateFile error\n"); делим, не был ли он с ж а т р а н е е . DWORD dwRes=0; b=DeviceloControl (h, FSCTL_GET_COMPRESSION, NULL, 0, &dwRes, 4, &dwBytesReturned, 0); ГЬ) printf ("DeviceloControl for FSCTL_GET_COMPRESSION ErrorW'); *e rMes == COMPRESSION_FORMAT_NONE ) //He сжат printf ("COMPRESSION^ FORMAT_ NONE\n"); else iffdwRes == COMPRESSION^ FORMAT^ DEFA ULT) II Сжат алгоритмом, описанным выше printf ("COMPRESSION_ FORMAT _ DEFA ULT\n "); else II Сжат неизвестным алгоритмом printf ("COMPRESSION^ FORMAT^ UNKNOWNS"); Если файл ранее не б ы л с ж а т , то с ж и м а е м е г о 1 . Дгортм по умолчанию WORD dwSrc = COMPRESSION FORMATDEFAULT; b:DeviceloContml(h, FSCTL_SET_COMPRESSION, &dwSrc, 4, &dwRes, 4, &dwBytesReturned, 0 ); IЩ pnntf ("DeviceloControl for FSCTL_SET_COMPRESSION ErrorW);
• шъ сжатый файл, система просто ничего не делает, поэтому проверку евыполнять. 319
О п р е д е л я е м р а з м е р ф а й л а б е з у ч е т а (GeJFfleSize) я сжатия (GetCompressedFileSize): DWORD dwSizeUnt/ICOMPRESSlON = GetFileSIze (h. 0): pnntf ("GetFileSize = %u\n". dwSizeUntilCOMPRESSION}; CloseHandle (h); DWORD dwSizeAfterCOMPRESSION = GetCompressedFileSizeCdata txl". 0 }; prinlf ("dwSizeAfterCOMPRESSION = %u\n dwSizeAfterCOMPRESSION): О б р а т и т е в н и м а н и е , ч т о п о с л е д н я я ф у н к ц и я псполыте п а ф а й л а , а н е д е с к р и п т о р , п о э т о м у ф а й л п р е д в а р и т е л ь н о змрым ется. Шифрование (Encrypt File System — EFS) E F S и с п о л ь з у е т с и м м е т р и ч н о е ш и ф р о в а н и е и технс.гоя» о т к р ы т ы х к л ю ч е й д л я з а щ и т ы ф а й л о в о т несанкццоннроыякг» д о с т у п а . С и м м е т р и ч н о е ш и ф р о в а н и е о б е с п е ч и в а е т шифра КАП ф а й л о в в р е ж и м е , к о г д а ш и ф р о в а н и е и р а с ш и ф р о в а н и е пиво н я е т с я о д и н а к о в ы м и л и л е г к о в ы ч и с л я е м ы м о д я и м и л др} « • к л ю ч о м . Д л я о б е с п е ч е н и я ц е л о с т н о с т и ф а й л о в нсполыулм ц и ф р о в а я подпись. Ц и ф р о в а я п о д п и с ь — это эашифромвш к о н т р о л ь н а я с у м м а ф а й л а . Д л я ш и ф р о в а н и я э т о й контро.ивй с у м м ы и с п о л ь з у е т с я л и ч н ы й к л ю ч п о л ь з о в а т е л я . Д л и пра ц и ф р о в о й п о д п и с и и с п о л ь з у е т с я о т к р ы т ы й к л ю ч , которы! п и с ы в а е т с я д о в е р е н н ы м ц е н т р о м . Т а к о й к л ю ч называется п ф р о в ы м с е р т и ф и к а т о м . И с п о л ь з о н п н и е к л ю ч е в о й п а р ы Loot р е а л и з о в а т ь м о д е л ь в з а и м н о г о н е д о в е р и я , к о г д а только владоя л и ч н о г о к л ю ч а м о ж е т п о д п и с а т ь д а н н ы е , а проверить э т у подла могут все, кто имеет цифровой сертификат. П о л ь з о в а т е л ь и с п о л ь з у е т з а ш и ф р о в а н н ы е ф а й л ы точно ш ж е , к а к д р у г и е ф а й л ы и п а н к и - П р о з р а ч н о е шифрование о ; е т , ч т о с и с т е м а а в т о м а т и ч е с к и р а с ш и ф р о в ы в а е т ф а й л ы и швш п р и доступе к и и м с а н к ц и о н и р о в а н н о г о пользователе К ф а й л с о х р а н я е т с я , в ы п о л н я е т с я ш и ф р о в а н и е . Если доступ г мш и ф р о в а н н о м у ф а й л у и л и п а п к е п ы т а е т с я п о л у ч и т ь посторонп! ч е л о в е к , д л я н е г о с и с т е м а ф о р м и р у е т с о о б щ е н и е о вапрете доступ» «Access denied*. В о с с т а н о в л е н и е д а н н ы х т а к ж е в о з м о ж н о в EFS, еслв Я п р е д у с м о т р е н о п о л и т и к о й б е з о п а с н о с т и д л я с и с т е м ы . К пржжрг, е с л и п о т е р я н ы с е р т и ф и к а т и л и ч н ы й к л ю ч ( н е читается с • к а и л и п о д р у г о й п р и ч и н е ) , в о с с т а н о в л е н и е данных возком: 320
<)щью специального а г е н т а в о с с т а н о в л е н и я . Е с л и к о м п ь ю т е р е с сервером W I N D O W S 2 0 0 0 , в к о т о р о м и с п о л ь з у е т с я A c t i v e iry. роль агента в о с с т а н о в л е н и я п р и с в о е н а п о у м о л ч а н и ю шстратору д о м е н а . Агент восстановления и м е е т с п е ц и а л ь н ы й с е р т и ф и к а т и с о вукяций ему л и ч н ы й к л ю ч , к о т о р ы й п о з в о л я е т в о с с т а н о г.данные. П о у м о л ч а н и ю п о л и т и к а в о с с т а н о в л е н и я к о н ф и г у • ся локально д л я а в т о н о м н о г о к о м п ь ю т е р а . Гтавной задачей а д м и н и с т р а т о р о в E F S я в л я е т с я р е з е р в и р о зашифрованных ф а й л о в , н а с т р о й к а п о л и т и к и в о с с т а н о в и I . Резервные к о п и и з а ш и ф р о в а н н ы х ф а й л о в т а к ж е ш и ф р у ^ , когда используются с р е д с т в а р е з е р в и р о в а н и я W I N D O W S к Рассмотрим п р о г р а м м н о е у п р а в л е н и е ш и ф р о в а н и е м ф а й л о в . Пусть необходимо з а ш и ф р о в а т ь ф а й л d a t a . t x t . Сначала проверим в о з м о ж н о с т ь и с п о л ь з о в а н и я р е ж и м а ш и ф ия(сл£. 8.7.3). Для шифрования и р а с ш и ф р о в а н и я ф а й л о в ( к а т а л о г о в ) п р и гсяфункции, п р и м е р ы и с п о л ь з о в а н и я к о т о р ы х п р и в е д е н ы
"Шифрование файла t=EncryptFile("data.txt"); ГЪ) printf ("EncryptFile — Error\n"); fee printf ("EncryptFile — OK\n"); Расшифрование файла h=DecryptFile(" data.txt", 0); i lib) printf ("DecryptFile — ErrorW); «se printf ("DecryptFile — OK\n"); E последней ф у н к ц и и в т о р о й п а р а м е т р з а р е з е р в и р о в а н и д о л бить равен 0. Дополнительные потоки в ф а й л е
Ншоминаем, что н а р я д у с о с н о в н ы м и д а н н ы м и в ф а й л е м о ж ."•пользовать д о п о л н и т е л ь н ы е п о т о к и . Т а к и е п о т о к и п р и м е н я ' 'станеобходимо з а п и с а т ь в ф а й л д а н н ы е , к о т о р ы е н е д о л ж Г'Ыть видимы о б ы ч н о м у п о л ь з о в а т е л ю . П р и м е р ы : ф а м и л и я чнка всегда п о з в о л и т у с т а н о в и т ь а в т о р с т в о п р о г р а м м ы ; 321
к о н т р о л ь н а я с у м м а ф а й л а п о з в о л и т п р о в е р и т ь целостность дави > го и л и д р у г и х ф а й л о в и т.д. Д л я с о з д а н и я д о п о л н и т е л ь н ы х п о т о к о в необходимо выбрать и м я потока в виде: И м я основного файла: И м я потока. Ф а й л с т а к и м и м е н е м м о ж н о о б р а б а т ы в а т ь с помощью станд а р т н ы х ф у н к ц и й WinApi д л я р а б о т ы с ф а й л а м и . П р и копирован и и ф а й л а н а у с т р о й с т в о , к о т о р о е н е п о д д е р ж и в а е т дополнительн ы х п о т о к о в , о н и т е р я ю т с я , п р и э т о м н и к а к и х о ш и б о к н е фикс* руется. Пример. З а п и с а т ь р а з м е р ф а й л а , о п р е д е л и в его с помощью л ю б о й п р о г р а м м ы . С ф о р м и р о в а т ь в ф а й л е a . h дополнительный п о т о к и з а п и с а т ь т у д а ф а м и л и ю Ivanov. П р о в е р и т ь размер исх о д н о г о ф а й л а . О н н е д о л ж е н и з м е н и т ь с я . П р о ч е с т ь содержимое д о п о л н и т е л ь н о г о п о т о к а , у б е д и в ш и с ь , что о н создан. // Создание дополнительного потока в файле a.h h = CreateFile ("a.hifio", GENERIC_WRITE, 0, 0, CREATE_ALWAYS. O.G if(h == INVAUD_HANDLE_VALUE) { printf ("CreateFile a.h:fio error n");
}{ //Запись туда фамилии DWORD dwCount; WriteFile (h, "Ivanov", 7, &dwCourit, 0); CloseHandle(h); // Проверка правильности записи h = CreateFile ("a.hifio", GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); if (h == INVALID_HANDLE_VALUE)
{ }
printf ("CreateFile return 1;
a.h:fio error\n");
charfio[10]; ReadFile (h, fio, 10, &dwCount, 0); CloseHandle(h); printf ("%s\n", fio);
} Создание и использование жестких связей (HardLink) П у с т ь н е с к о л ь к о п р о г р а м м и с т о в з а н и м а ю т с я разработкой о д н о г о п р и л о ж е н и я . В с е м п о л ь з о в а т е л я м н е о б х о д и м о использов а т ь о д н и и т е ж е з а г о л о в о ч н ы е ф а й л ы . М о ж н о д л я каждого по.ть322
еля задать свою к о п и ю — но э т о п л о х о , т а к к а к н е к о т о р ы е ватели будут п р и м е н я т ь н е а к т у а л ь н ы е к о п и и . М о ж н о п о д ьодни и те же ф а й л ы — но э т о п л о х о , т а к к а к п о д к л ю ч е н и е вочных файлов н е и з т е к у щ е г о к а т а л о г а н е у д о б н о , т р е б у е т ня конкретного к а т а л о г а в и с х о д н о м т е к с т е . Н а и л у ч ш и м ним является и с п о л ь з о в а н и е ж е с т к о й с с ы л к и н а о р и г и н а л ь файч. Количество с с ы л о к н а о д и н и т о т ж е ф а й л м о ж е т б ы т ь , в этом случае л ю б ы е и з м е н е н и я л ю б о й к о п и и ф а й л а п р и кпзменению всех с с ы л о к на н е г о . Для создания жесткой с с ы л к и и с п о л ь з у е т с я ф у н к ц и я WinApi: BOOL CreateHardLinkf LPCTSTR IpFileName, LPCTSTR IpExistingFileName, LPSECURITY_ATTRIBUTES IpSecurityAttributes
tefifeName — имя новой с с ы л к и ; IpExistingFileName — и м я о р и г и н а л ь н о г о ф а й л а ; IpSecurityAttributes — п а р а м е т р ы б е з о п а с н о с т и д л я с с ы л к и . Пример создания ж е с т к о й с с ы л к и н а з а г о л о в о ч н ы й ф а й л тр \a.h в текущем к а т а л о г е : г CreateHardLinkf "d: 11tmp Wa.h", "a.h",0); Щ printf ("CreateHardLink — ErrorW); else printf С CreateHardLink—OK\n"); Любые обращения к ф а й л у a . h из т е к у щ е г о к а т а л о г а э к в и в а гны обращениям к о р и г и н а л ь н о м у ф а й л у . Мониторинг изменений файлов и каталогов Дтя отслеживания и з м е н е н и й в ф а й л а х и к а т а л о г а х м о ж н о оэовать: -специальные, ф у н к ц и и WinApi; журнал изменений, к о т о р ы й п о д д е р ж и в а е т N T F S . Использование с п е ц и а л ь н ы х ф у н к ц и й WinApi. Футцкя FindFirstChangeNotificatiori. Определяет первое и з м е н е н и е . HANDLE FindFirstChangeNotificationf LPCTSTR IpPathName, BOOLbWatchSubtree, 323
DWORD dwNotifyFilter ); где: IpPathNeme — к а т а л о г , к о т о р ы й п р о в е р я е т с я ; bWatChSubtree — н у ж н о ли о т с л е ж и в а т ь и з м е н е н и я вяутр» дерева; dwNotifyFilter — о п р е д е л я е т , ч т о о т с л е ж и в а т ь . П о с л е д н и й п а р а м е т р з а д а е т с я о д н и м и з флагов: FILE_NOTIFY_CHANGE_DIR_NAME — изменение имени и та лога (файла): FILE_NOTIFY_CHANCE_ATTRIBUTES
—
изменение
атрвбр
тов; FILE NOTIFY CHANGE SIZE — и з м е н е н и е размеров: FILE_NOTIFY_CHANGE_LAST_WRITE — изменение еремлх последней знписи; FILE_ NOTIFY CHANGE_SECURITY — и з м е н е н и е пврамегрм безопасности. М о ж н о о д н о в р е м е н н о з а д а т ь н е с к о л ь к о ф л а г о в через сянм< Функция
FindNextChangeNolificehon-
Определяет очередное изменение. HANDLE FindNextChengeNotlfication (НА NDLE
ftHande/;
В э т о й ф у н к ц и и hHandle — д е с к р и п т о р , возвращенный предыдущей функцией. Функция FindCloseCbangeNohfication ({HANDLE Завершает отслеживание изменений.
Mandle);
Функции FindFirstChangeNotificalion, FlndNextChangeNoti cation н е п е р е д а ю т у п р а в л е н и я с л е д у ю щ е й ф у н к ц и и , если нет»м е н е н и й т о г о т и п а , к о т о р о е з а д а н о ф у н к ц и е й п о и с к а первого изм е н е н и я . Д л я о т с л е ж и в а н и я и з м е н е н и й н е о б х о д и м о испапьлонт | о д н у и з ф у н к ц и й о ж и д а н и я , н а п р и м е р , WaitForSingleObject. Пример. З а п и ш е м к о д д л я о т с л е ж и в а н и я изменений и т е к у щ е м каталоге и во всех внутренних каталогах. // Определение текущего каталога char CurrentDirectoryjMAX_PATH); CetCurrentDireclory (sizeof (CurrenlDirectory). СиоепЮгвсЮу). //Начало отслеживания h = FindFirstChangeNotification(CurrenlDirectory. true. FILE_ NOTIF Y__CHANGE_ F!LE_ NAME ). 324
i(inti-0;i<5;i++) WaitForSingleObject (h, INFINITE); printf ("Change Files %d\n", i); FindNextChangeNotification(h); k^CloseChangeNotificationfh );
досмотренный в ы ш е к о д п о з в о л я е т о т с л е д и т ь 5 и з м е н е н и й , чего отслеживание з а в е р ш а е т с я (FindCloseChangeNotrfication). статном этого кода я в л я е т с я т о , ч т о м ы н а к а ж д о м ш а г е н е . , что произошло, к а к о й н о в ы й ф а й л и л и к а т а л о г п о я в и л с я , jfl определения п р о и з о ш е д ш и х и з м е н е н и й о н и м о г у т б ы т ь вы в структуру т и п а FILE NOTIFYJNFORMA TION: fldefstruct_FILE_NOTIFY_INFORMATION { DWORD NextEntryOffset; DWORD Action; DWORD FileNameLength; WCHAR FileName[1]; c ILE_NOTIFY_ INFORM A TION; Шате — имя ф а й л а , в к о т о р о м п р о и з о ш л о и з м е н е н и е ; jp/ameLenc/fh — д л и н а э т о г о и м е н и ; 1с!юл — определяет, ч т о к о н к р е т н о п р о и з о ш л о ( з а д а е т с я , к а к дая dwNotifyFilter в ф у н к ц и и FindFirstChangeNotification). talEntryOffset — смещение д л я о ч е р е д н о й з а п и с и и з м е н е н и й . Обратите внимание, ч т о и м я ф а й л а з а д а е т с я в ф о р м а т е UNI1м мониторинга и з м е н е н и й с з а п и с ь ю в с т р у к т у р у и с п о л ь -а функция ReadDirectoryChangesW: iJOL ReadDirectoryCflangesW(HANDLE hDirectory, JVOID IpBuffer, DWORD nBufferLength, BOOL bWatchSubtree, WRD dwNotifyFilter, LPDWORD IpByfesReturned, OVERLAPPED IpOverlapped, ifWERLAPPEDCOMPLETIONROUTINE IpCompletion Routine); 'Directory — дескриптор к а т а л о г а , к о т о р ы й а н а л и з и р у е т с я ; W e r — буфер д л я з а п и с и р е з у л ь т а т а , м о ж е т б ы т ь з а п и с а н о дко изменений; lMerLength — размер и с х о д н о г о б у ф е р а ; MatchSubtree — о п р е д е л я е т н е о б х о д и м о с т ь и с с л е д о в а н и я • ' '"ЕНПХ каталогов; 325
dwNotifyFilter — у к а з ы в а е т , ч т о о т с л е ж и в а т ь ; IpBytesReturned — с к о л ь к о б а й т о в с ф о р м и р о в а н о буфч« IpOverlapped — с т р у к т у р а д л я а с и н х р о н н о г о вызова; IpCompletionRoutine — ф у н к ц и я , к о т о р а я вызывается s * чае изменений. Пример использования функции: PBYTE * fni = new BYTE [sizeof (FILE_NOTIFYJNFORMAT' MAX_PATH], ReadDirectoryChangesW(h, fni, sizeof (fni), false, FILE_NOTIFY_CHANGE_FILE_NAME, &dwBytesReturmC NULL, NULL), II Если за это время произошли какие-то изменения printf ("File Name = %S\n", fni.FileName); II выведем имя файла, который появился Использование журнала Р а с с м о т р е н н ы е в ы ш е ф у н к ц и и п о з в о л я ю т отследить я 4 | н и я в ф а й л а х и к а т а л о г а х , но м о н и т о р и н г изменений начн '.*п о с л е з а п у с к а ф у н к ц и и ReadDirectoryChangesW или функцй т FirstChangeNotification, FindNextChangeNotification. Отг- » и з м е н е н и я , п р о и с х о д я щ и е в о в р е м я , к о г д а приложение t c i n ф у н к ц и я м и н е з а п у щ е н о , н е л ь з я , к р о м е того, нет поля вреиг: п о к о т о р о м у м о ж н о б ы л о б ы о п р е д е л и т ь , к о г д а произошла л нения. Д л я р е ш е н и я т а к и х з а д а ч и с п о л ь з у е т с я системный иу)Ш С и с т е м н ы й ж у р н а л м о ж е т б ы т ь з а д а н д л я к а ж д о г о NTFS » u Д л я с о з д а н и я т а к о г о ж у р н а л а н е о б х о д и м о и м е т ь привт I | м и н и с т р а т о р а . В ж у р н а л з а п и с ы в а е т с я и н ф о р м а ц и я об уда. ж д о б а в л е н и и и л и м о д и ф и к а ц и и ф а й л а . К а ж д о й такоь o r в Ш с о о т в е т с т в у е т о д н а з а п и с ь в ж у р н а л е . М о ж н о , конечно, к а м в р е м е н и о п р е д е л и т ь в с е ф а й л ы , в к о т о р ы х происхол i о м е н е н и я , н о э т о д л я б о л ь ш и х д и с к о в д о л г о , журнал зна к б ы с т р е е . К а ж д а я з а п и с ь в ж у р н а л е с о д е р ж и т приблизит) • 8 0 - 1 0 0 б а й т о в , н о е с т ь о г р а н и ч е н и я п о р а з м е р а м этого» ра» Е с л и р а з м е р ж у р н а л а п р е в ы ш е н , у д а л я ю т с я самые старье « с и . Д л я д о с т у п а к з а п и с я м ж у р н а л а и с п о л ь з у е т с я функция У "А; DeviceloControl, т . е . р а б о т а с ж у р н а л о м осуществляется с сгв щью драйвера. П р и м е р ы к о д о в , к о т о р ы е м о ж н о использовать для с ж у р н а л о м и з м е н е н и й , з а д а н ы в табл. 8.4. 326
Таблица К
8.4
Создание нового журнала регистрации изменений на диске или модификация существующего.
JEATEJSNJOURNAL
Удаление журнала регистрации изменений на диске или ожидание извещения об удалении такого журнала.
V.'B.ETEJJSNJOURNAL
%jmjJSN_DATA -
Отметка заданного файла или каталога о том, что д л я него должны записываться изменения.
mmDLE
:.
Запросы на информацию из текущего журнала о его записях и объеме.
'.MJJSNJOURNAL
R KAD USNJOURNAL
Восстановление данных по записям из журнала между двумя заданными записями.
Kt°TE_USN_CLOSE_RECORD
Генерирует запись в журнале изменений д л я входного файла. В этой записи будет установлен бит USN_REASON_CLOSE.
аотрим программу для р а б о т ы с ж у р н а л о м : Mjuii dm работы с журналом определены в заголовочном ti.h таким образом: 1 _Ш_ШМТ>= 0x0500) и и константы для работы с журналом, поэтому опретанту _ WIN32_ WIN NT
<-n_Wm2_WINNT 0x0500 шции предполагают использование UNICODE, поэтому v -оноптанты UNICODE КР e_UNICODE "tjle le<winioct/.h> e e<stdio.h> Ш Enlarge, char**argv) 327
TCHAR tcCurBuffer[MAX_PATH]; GetCurrentDirectory (sizeof (tcCurBuffer)/sizeof (TCHAP* tcCurBuffer); TCHAR tcDrive[MAX_PATH]; wsprintf (tcDrive, TEXT("\\\\M%c:"), tcCurBuffer[0]) printf ("%S\n", tcDrive); HANDLE hDrive; for (int i = 0; i < 5; i++) { hDrive = CreateFile (tcDrive, GENERIC READ FILE SHARE_READ | FILE_SHARE_WRITE OPEN_EXISTING, 0, 0); if (hDrive != INVALID_HANDLE_VALUE) break
}
if (i ==5) { printf ("CreateFile Error\n"); return 1;
} else printf ("CreateFile OK\n"); DWORD dwCount; Г typedef struct { DWORDLONG MaximumSize; DWORDLONG AllocationDelta } CREATE USN JOURNAL DATA, 'PCREATE USNJOURNAl 7
CREATE^USN_JOURNAL_DATA CreateUSNJournalData-t DWORD BytesReturned; BOOL b = DeviceloControl (hDrive, FSCTL_CREATE_USN JOURNAL, &CreateUSNJournalDi sizeof (CreateUSNJournalData), 0 0 &BytesReturned 0) if (!b) printf ("DeviceloControl — Error\n ); else printf ("DeviceloControl — OK\n"): USN_JOURNAL DATA JournalData; b = DeviceloControl( hDrive, // handle to volume FSC TL_Q UERY_ USN_ JO URN A L, // dwIoContrc NULL, // IplnBuffer 0, //nlnBufferSize &JoumalData, //output buffer sizeof (JournalData), //size of output buffer &BytesReturried // number of bytes returned О // OVERLAPPED structure
);
if Ob) 328
{
printf (TSCTL_QUERY_USN_ JOURNAL — Ermr\n");
I elsef printf ("FSCTL_QUERY_USN_JOURNAL — OK\n"); printf ("JournalData.UsnJournallD = %/64x\n", JournalData. UsnJournallD); pnntf (JournalData.MaximumSize = %l64x\n", JournalData. MaximumSize); printf ('JournalData. AllocationDetta = %l64x\n", JournalData. AllocationDelta); I if (argc > 1) { DELETE_USN_ JOURNADATA DeleteData DeleteData.UsnJournallD = JournalData.UsnJournallD; DeleteData. DeteteFlags = USN_DELETE_FLAG_DELE OELETEFLAG NO TIF Y; b = DeviceloControl( hDrive, //handle to volume FSCTLDELETEUSNJOURNAL, II dwIoControlCode (LPVOID) &D eleteData, // input buffer (DWORD) sizeof (DeleteData), //size of input // buffer NULL, //IpOutBuffer 0, //nOutBufferSize &BytesReturned, // number of bytes returned ОIIOVERL A PPED structure ); if(b) printf ("Delete Journal— OK\n"); else printf ("Delete Journal — Error\n"); return 0;
) READ_USN_JOURNAL_DA ТА ReadData = {0}; ReadData.UsnJournallD - JournalData.UsnJournallD; ReadData.StartUsn = JournalData. FirstUsn; ReadData.ReasonMask = USN__REASON DATA_0VERWRlТЕ; ' wмаются изменения, связанные с изменением данных JIUSN_REASON_CLOSE;
/^омяение о закрытии журнала до з а п и с и д а н н ы х г вменении
charbutfer[40960];/l = new char [JournalData. AllocationDelta]; 329
USN *NextRecord = (USN *)buffer; char *pAlignAddress = (char")((char*)buffer + 8); USN_RECORD Record = (PUSN RECORD)(((DWORD) (pAlignAddress + 7)) & (~7) ); wcharj FileName[MAX_PATHJ; for (i = 0; i < 100; i++) { printf ("ReadData. StartUsn = %l64d\n", ReadData. StartUsn); b = DeviceloControlf hDrive // handle to volume FSC TL_ READ_ USN_JOURNAL // dwIoControlC &ReadData, // input buffer sizeof (ReadData), // size of input buffer //&NextRecord, // output buffer buffer, sizeof (JournalData. MaximumSize), // size of output //buffer &BytesReturned, // number of bytes returned 0 // OVERLAPPED structure
);
if (lb) { printf ("Error read\n");
break;
}
else printf ("OK
Read\n");
//ReadData. StartUsn = *NextRecord, ReadData. StartUsn = * NextRecord //JournalData if (ReadData. StartUsn >=JournalData.MaxUsnj break memcpy (FileName, record->FiteName, record->FileNameLength) FileName[record->FileNameLength] = 0; printf ("File name = c/oS\n", record->FileName);
} }
CloseHandle return 0;
(hDrive);
Квоты д и с к а
О п р е д е л я ю т п р е д е л ь н ы е р а з м е р ы д и с к о в о г о пространства д л я ф а й л о в п о л ь з о в а т е л я и л и т о м о в . К в о т а д л я т о м а определи д а ж е е с л и т о м а н а х о д я т с я н а р а з л и ч н ы х д и с к а х . В случае запрос 330
ш дисковом п р о с т р а н с т в е п о л ь з о в а т е л ю с о о б щ а е т с я с в о г с т р а н с т в о с учетом к в о т ы . Е с л и п о л ь з о в а т е л ь п ы т а е т с я . этьвыделенную к в о т у , с и с т е м а ф о р м и р у е т с о о б щ е н и е , ч т о :вый. Напоминаем, ч т о д и с к о в о е п р о с т р а н с т в о в ы д е л я е т Ьоты того пользователя, к о т о р ы й я в л я е т с я с о б с т в е н н и к о м Глбственник файла о п р е д е л я е т с я и д е н т и ф и к а т о р о м б е з ш (security i d e n t i f i e r ( S I D ) ) д л я ф а й л а . А д м и н и с т р а т о р ^•квотами. Могут б ы т ь у с т а н о в л е н ы с л е д у ю щ и е р е ж и м ы Таблица
8.5
Режимы для управления д и с к о в ы м и к в о т а м и '4R ние
Описание
И г дается Состояние по у м о л ч а н и ю . В^лся
Квота задается, но не у ч и т ы в а е т с я . В этом состоянии события, с в я з а н н ы е с п р е в ы ш е н и е м к в о т ы , не генерируются.
* ..ется 'ется
Квота задается и у ч и т ы в а е т с я . В э т о м с о с т о я н и и события, связанные с п р е в ы ш е н и е м к в о т ы , генерируются.
! та может быть у с т а н о в л е н а д л я л о к а л ь н ы х и у д а л е н н ы х елей. При этом на к о м п ь ю т е р а х д о л ж н а б ы т ь у с т а н о в л е н j. Квоту может у с т а н о в и т ь т о л ь к о а д м и н и с т р а т о р . Множество п о т о к о в
^поддерживает запись н е с к о л ь к и х п о т о к о в ( н е з а в и с и 3 Млей файла) внутри о д н о г о ф а й л а . К а ж д ы й п о т о к и м е е т в жество атрибутов, р а з м е р о в . И с п о л ь з у я м н о ж е с т в о п о ?, ла, он может а с с о ц и и р о в а т ь с я с н е с к о л ь к и м и п р и л о 8одновременно, т а к и м и к а к M i c r o s o f t W o r d и W o r d P a d , iep. Если файл к о п и р у е т с я на д и с к с ф а й л о в о й с и с т е м о й , . не поддерживает п о т о к о в ( л ю б а я F A T ) , то п о т о к и т е р я ю т 1 !г ни можно использовать д л я з а п и с и « н е в и д и м о й и н ф о р > например, данных о р а з р а б о т ч и к е . В з т о м с л у ч а е м о ж н о • № взять авторские п р а в а на п р о г р а м м у . Восстанавливаемость N T F S
fTFS - восстанавливаемая ф а й л о в а я с и с т е м а , к о т о р а я •~1ет целостность т о м а , и с п о л ь з у я т е х н о л о г и ю р е г и с т р а IQUАкций. NTFS р а с с м а т р и в а е т к а ж д у ю о п е р а ц и ю , к о т о •Илфищфует файл, к а к т р а н з а к ц и ю и у п р а в л я е т е ю , к а к 331
е д и н ы м ц е л ы м . П о с л е е е н а ч а л а т р а н з а к ц и я либо завершай б л а г о п о л у ч н о , и л и , в с л у ч а е п р о б л е м , д е л а е т о т к а т назад (том N.. в о з в р а щ а е т с я в и с х о д н о е с о с т о я н и е д о н а ч а л а транзакции). NT" с н а ч а л а з а п и с ы в а е т о п е р а ц и и , к о т о р ы е д о л ж н ы быть выполвев. в ж у р н а л . К о г д а и н ф о р м а ц и я о т р а н з а к ц и и полностью залня • в ж у р н а л , N T F S в ы п о л н я е т з а п и с а н н ы е о п е р а ц и и в кэше джи П о с л е о б н о в л е н и я к э ш а в ж у р н а л з а п и с ы в а е т с я инфоруашн t з а в е р ш е н и и т р а н з а к ц и и . В п р о ц е с с е в о с с т а н о в л е н и я NTFS • в т о р н о в ы п о л н я е т к а ж д у ю о п е р а ц и ю , з а п и с а н н у ю в ж урна* К о г д а N T F S н а х о д и т в ж у р н а л е т р а н з а к ц и и , которые н е бы; в е р ш е н ы и з - з а с б о я с и с т е м ы , э т и о п е р а ц и и просто нсключа! и з ж у р н а л а . Д а н н у ю о п е р а ц и ю в ы п о л н я е т ф у н к ц и я носста„ • > н и я . Ф у н к ц и я в ы п о л н я е т с я о ч е н ь б ы с т р о и н е требует болиш в ы ч и с л и т е л ь н ы х з а т р а т . N T F S а в т о м а т и ч е с к и проверяет нал it» н е п о л н ы х т р а н з а к ц и й по ж у р н а л у и у н и ч т о ж а е т ссютветств 1 щ и е з а п и с и п р и з а г р у з к е О С . К о н е ч н о , в э т о м случае могу И п о т е р я н ы н е к о т о р ы е д а н н ы е п о л ь з о в а т е л я , н о целостность * ' Ф С н е н а р у ш и т с я . N T F S т а к ж е и с п о л ь з у е т т е х н и к у нзме~ i к л а с т е р а д л я м и н и м и з а ц и и п о т е р ь , с в я з а н н ы х с использован*» п л о х и х с е к т о р о в . К о г д а о б н а р у ж е н п л о х о й с е к т о р при записи, с т е м а а в т о м а т и ч е с к и в ы д е л я е т н о в ы й с е к т о р д л я данных. В ч г п л о х о г о с е к т о р а з а п и с ы в а е т с я в с п е ц и а л ь н ы й файл. Этот с только обнаружен плохой сектор.
8 . 7 . 4 . Ф а й л о в а я система для компакт-дисков (Compact Disc File System) W I N D O W S 2 0 0 0 п о д д е р ж и в а е т р а б о т у с CDFS, которв? г з в о л я е т и с п о л ь з о в а т ь ф а й л ы с д л и н н ы м и и м е н а м и , удовле; ю щ и м и с т а н д а р т у I S O 9 6 6 0 . С о г л а с н о э т о м у стандарту, есть - <» ограничения: — и м е н а п а п о к и ф а й л о в д о л ж н ы б ы т ь не длиннее 32 ( Ш лов; — в с е и м е н а ф а й л о в и п а п о к д о л ж н ы б ы т ь заданы за1 .AI» ми буквами; 332
уровень вложенности д о л ж е н б ы т ь н е б о л е е 8 , н а ч и н а я
я: расширения для ф а й л о в з а д а в а т ь не о б я з а т е л ь н о .
8.8. Работа с устройствами
8.8.1. Функции GetLogicalDrives, GetLogicalDriveStrings I1 пользуются для о п р е д е л е н и я т е к у щ и х д о с т у п н ы х у с т -
: Ш) Gef LogicalDrives(VOID); Нкция возвращает б и т о в у ю м а с к у д л я у с т а н о в л е н н ы х ' тв. Бит 0 соответствует у с т р о й с т в у А, б и т 1 — у с т р о й с т в у ) . t u ошибка, то ф у н к ц и я в о з в р а щ а е т 0. "ORD GetLogicalDriveStrings ( BNOR&ufferLength, LPTSTR IpBuffer
"ufferLength - размер б у ф е р а д л я в с е х у с т р о й с т в ; Мег— буфер для у с т р о й с т в . У с т р о й с т в а з а д а ю т с я в в и д е |улевой завершитель>. П о с л е п о с л е д н е г о у с т р о й с т в а с п и тся два нулевых з а в е р ш и т е л я . 8.8.2. Функция GetVolumelnformation XGetVolumelnformation ( ."CTSTR IpRootPathName, pSTR IpVolumeNameBuffer, WORD nVolumeNameSize, JPDWORD tp VolumeSerialNumber, 'SDWORDIpMaximumComponentLength, .'WORD IpFileSystemFlags, .'TSTRIpFileSystemNameBuffer, WORD nFileSystemNameSize
'thName — к о р н е в о й к а т а л о г д л я р а з д е л а д и с к а ; UNameBuffer — и м я р а з д е л а ; 'ameSize — р а з м е р б у ф е р а д л я и м е н и р а з д е л а ; clumeSerialNumber— с е р и й н ы й н о м е р р а з д е л а ; mmComponentLength — м а к с и м а л ь н а я д л и н а ф а й л а ; 333
IpFileSystemFlags — ф л а г и ф а й л о в о й с и с т е м ы ; FS_CASE_IS__PRESERVED — и м я ф а й л а — регистро-к чувствительное; FS_CASE_SENSITIVE — и м я ф а й л а — регистро-чувствп тельное; FS_UNICODE_STORED_ON_DISK — имя файла можг б ы т ь з а д а н о в UNICODE; FS_FILE_COMPRESSION — ф а й л о в а я система поддержи вает с ж а т ы е тома; FS_VOL_IS_COMPRESSED — д а н н ы й р а з д е л сжатый: IpFileSystemNameBuffer — и м я ф а й л о в о й с и с т е м ы ; nFileSystemNameSize — д л и н а п о л я и м е н и Ф С ; 8.8.3. Функция
SetVolumeLabel
BOOL SetVolumeLabel( LPCTSTR IpRootPathName, LPCTSTR IpVolumeName ); IpRootPathName — к о р н е в о й к а т а л о г д л я р а з д е л а диска; IpVolumeName — м е т к а р а з д е л а . 8.8.4. Функция
GetDriveType
И с п о л ь з у е т с я д л я о п р е д е л е н и я т и п а устройства. UINT GetDriveTypef LPCTSTR IpRootPathName У. где: IpRootPathName — к о р н е в о й к а т а л о г д л я р а з д е л а дпска. Ф у н к ц и я возвращает тип устройства: 0 — т и п устройства не м о ж е т б ы т ь определен. 1 — к о р н е в о й к а т а л о г д л я р а з д е л а д и с к а н е существует. DRIVE REMOVABLE — с м е н н ы й д и с к . DRIVE_FIXED — ж е с т к и й д и с к . DRIVE REMOTE — у д а л е н н о е у с т р о й с т в о (сетевое) driv*. DRIVECDROM — CD-ROM. DRIVE_RAMDISK — у с т р о й с т в о в п а м я т и (RAM-диск). 8.8.5. Функция
GetDiskFreeSpace
И с п о л ь з у е т с я д л я о п р е д е л е н и я р а з м е р а сектора и кластера, а т а к ж е о б щ е г о ч и с л а к л а с т е р о в и к о л и ч е с т в а свободных кластер ». 334
LCetDiskFreeSpace ( USTR IpRootPathName, DWORD IpSectorsPerCluster, f/ORD IpBytesPerSector, WORD IpNumberOfFreeClusters, WORD IpTotalNumberOfClusters
pelhName — и м я р а з д е л а д и с к а . З а д а е т с я в ф о р м а т е , уе Буква определяет з а д а н н ы й р а з д е л ; xtorsPerCluster — к о л и ч е с т в о с е к т о р о в в к л а с т е р е ; ftesPerSector— к о л и ч е с т в о б а й т о в в с е к т о р е ;
FreeClusters — к о л и ч е с т в о с в о б о д н ы х к л а с т е р о в ; WlfdslNumberOfClusters — о б щ е е к о л и ч е с т в о к л а с т е р о в . .8.6. Функция CetDiskFreeSpaceEx | | отличие о т предыдущей ф у н к ц и и п о з в о л я е т о п р е д е л и т ь дню для заданного к а т а л о г а , в т о м ч и с л е и д л я к о р н е в о г о шучаеработает, к а к п р е д ы д у щ а я ф у н к ц и я ) . Ш. GetDiskFreeSpaceEx ( ;PCJSTR IpDirectoryName,
mRCEJNTECERIpFreeBytesAvailableToCaller, mGEJNTEGER IpTotalNumberOfBytes, //общее число байт Ут диске '"JLARGEJNTEGER IpTotalNumberOfFreeBytes // общее число | свободных байт на диске глкцпя возвращает 0, если о ш и б к а ( н е в е р н о з а д а н о у с т р о й -
J;ivepпрограммы д л я о п р е д е л е н и я п а р а м е т р о в д и с к о в . * : Ue<stdio.h>
ri "iam (j charcDevices[]="A:\\"; char VolumeNameBuffer[MAX_PATH], FileSystemNameBuffer-[MAX_PATH]; DWORD dwVolumeSerialNumber, dwFileSystemFlags;
dwMaximumComponentLerigth,
UltJI uError = SetErrorMode(SEM_ FA ILCRITICALERRORS); DWORD dwDevices = GetLogicalDrives(); lor (int i = 0; dwDevices; i++) 335
if (dwDevices & 1)
{ }
cDevicesfO] = A' + i; printf ("%s\n" cDevices);
II Тип диска DWORD dwDriveType = GetDriveType( cDevices У boot b = GetVolumelnformationf cDevices, VolumeNameBuffer, sizeof (VolumeNameBuffer) &dwVolumeSerialNumber &dwMaximumComponentLength, &dwFileSystemFlags, FileSystemNameBuffer, sizeof (FileSystemNameBuffer) y. if(b){ printf("Name is %s\n", VolumeNameBuffer) prtntf("VolumeSerialNumber = %x\n", dwVolumeSerialNumber); pnntf ("MaximumLengthOfFileName = %d\n dwMaximumComponentLength); if ( dwFileSystemFlags & FS_CASE_IS_PRESERVEC printf ("Not case of filenames\n") if (dwFileSystemFlags & FS_CASE_SENSITIVE) printf ("case-sensitive filenames\n) if (dwFileSystemFlags & FS_UNICODE_STORED_ON_DISK) printf (" UNICODE filenames\n ) if (dwFileSystemFlags & FS_FILE_COMPRESSION) printf (" file system supports file-based compress* • I if (dwFileSystemFlags & FS_VOLJS_COMPRESSEC printf (" he specified volume is a compressed "volume\n"); printf ("FileSystem = %s\n", FileSystemNameBuffer) // Параметры диска DWORD dwSectorsPerCluster dwBytesPerSector dwNumberOfFreeClusters, dwTotalNumberOfCluslr b = GetDiskFreeSpace( cDevices, &dwSectorsPerCluster, &dwBytesPerSector, &dwNumberOfFree Clusters, 336
&dwTotalNumberOfClusters
);
}
printf ("dwSectorsPerCluster = %u, " " dwBytesPerSector = %u\n" "dwNumberOfFreeClusters =" "%u dwTotalNumberOfClusters = %u\n", dwSectorsPerCluster, dwBytesPerSector, dwNumberOfFreeClusters, dwTotalNumberOfClusters);
dwDevices »=1;
J
SetEmMode(uError); return 0;
JM- ЛЬТЯТЫ
работы п р о г р а м м ы
ierialNumber = 0 BjmLengthOfFileName = 255 Btase of filenames i;,CODE filenames fttfyslem = FAT ^SectofsPerCluster = 1, dwBytesPerSector = 5 1 2 vmberOfFreeClusters = 2037 dwTotalNumberOfClusters = 2847 №is eSerialNumber = 0 :"iunLengthOfFileName = 255 . case of filenames '"ODE filenames fSjstem = FAT WorsPerCluster = 1 , dwBytesPerSector = 512 OfFreeClusters = 2037 dwTotalNumberOfClusters = 2847
fiSerialNumber = 11551ee5 imLengthOfFileName = 255 з of filenames CODE filenames em = FAT32 jrsPerCluster = 8 , dwBytesPerSector = 512 mberOfFreeClusters = 117386 dwTotalNumberOfClusters = 511058 s New Volume SerialNumber = 907d7c1f lumLengthOfFileName = 255 337
Not case of filenames case-sensitive filenames UNICODE filenames file system supports file-based compression FileSystem = NTFS dwSectorsPerCluster = 8 , dwBytesPerSector = 512 dwNumberOfFreeClusters = 558219 dwTotalNumberOfCluste - = 1074338 E:\ Name is VolumeSerialNumber = c8542816 MaximumLengthOfFileName = 255 Not case of filenames case-sensitive filenames UNICODE filenames file system supports file-based compression FileSystem = NTFS dwSectorsPerCluster = 8 , dwBytesPerSector = 512 dwNumberOfFreeClusters = 15561069 dwTotalNumberOfCluste i 29310584 FA G:\ Name is NEW VolumeSerialNumber = 922ed2df MaximumLengthOfFileName = 110 case-sensitive filenames UNICODE filenames FileSystem = CDFS dwSectorsPerCluster = 1 , dwBytesPerSector = 2048 dwNumberOfFreeClusters = 0 dwTotalNumberOfClusters = 225697 Д л я т о г о , ч т о б ы п р и о т с у т с т в и и в н е ш н е г о устройства (.л к е т ы ) п р о г р а м м а н е в ы д а л а с о о б щ е н и я о б о ш и б к е , устано • р е ж и м о б р а б о т к и с и с т е м н о й о ш и б к и ( ф у н к ц и я SetErrorMofc К а к в и д н о и з р е з у л ь т а т о в р а б о т ы , п р о г р а м м а в ы д а е т информаг о б о в с е х р а з д е л а х д и с к о в , у с т а н о в л е н н ы х н а компьютере. Так л и д и с к е т ы н е т , т о и н ф о р м а ц и я о е е и м е н и п р о п у щ е н а . Просмотри: внимательно результаты работы.
8.9. Работа с файлами З д е с ь б у д у т р а с с м о т р е н ы о с н о в н ы е ф у н к ц и и WinApi для б о т ы с ф а й л а м и . Б о л ь ш а я ч а с т ь э т и х ф у н к ц и й позволяет работал с ф а й л о м н е з а в и с и м о о т Ф С . Ф а й л ы м о ж н о обрабатывать в 338
s. Синхронный в в о д - в ы в о д п р е д п о л а г а е т , ч т о о п е р а ц и я юда должна быть з а в е р ш е н а до н а ч а л а в ы п о л н е н и я о ч е ператора программы. А с и н х р о н н ы й в в о д - в ы в о д р а з р е ш е н и е очередного о п е р а т о р а д о з а в е р ш е н и я о п е р а ц и и вода. м создания объекта я д р а д л я ф а й л а и с п о л ь з у е т с я ф у н к ц и я Эта функция в о з в р а щ а е т д е с к р и п т о р ф а й л а , к о т о р ы й нет адрес объекта я д р а , и л и н о м е р э т о г о о б ъ е к т а . В л ю б о м "криптор файла з а д а е т м е с т о в п а м я т и , г д е н а х о д и т с я ия о файле. И н ф о р м а ц и я о ф а й л е с о д е р ж и т и н ф о р м а •рая задается д л я ф а й л а в Ф С , и д о п о л н и т е л ь н у ю и н ф о р Дополнительная и н ф о р м а ц и я в к л ю ч а е т в с е б я т е к у щ и й 1 в файле. Все о с т а л ь н ы е о п е р а ц и и д л я ф а й л а р а б о т а ю т ром. После в ы п о л н е н и я т р е б у е м ы х о п е р а ц и й н а д ф а й SJMTI, выделенная под о б ъ е к т я д р а ф а й л а , д о л ж н а б ы т ь ена (функция CloseHandle). Д л я ч т е н и я - з а п и с и ф а й л о в 'ся функции ReadFile, WriteFile. Д л я з а д а н и я п о з и ц и и е для очередной о п е р а ц и и и с п о л ь з у е т с я ф у н к ц и я SetFile-
Ь.9.1. Функции CreateFile и CloseHandle Функции CreateFile -'ЖЕ CreateFile ( ктт IpFileName,// Имя файла [WORDdwDesiredAccess, //Режимы доступа к файлу DWORD dwShareMode, // Режимы совместного доступа IPSECURITY ATTRIBUTES IpSecurityAttributes, //Атрибуты '•безопасности OHORD dwCreationDistribution, // Как создавать DWORD dwFlagsAndAttributes, // Флаги и атрибуты файла IMlEhTemplateFi/e //Дескриптор файла с атрибутами шроеания
)
!>этестве имени файла м о ж н о з а д а в а т ь н е т о л ь к о и м я о б ы ч на, но и имя устройства. Мы и с п о л ь з о в а л и и м я у с т р о й 1 функции CreateFile п р и ч т е н и и - з а п и с и с е к т о р о в д и с к а Ш).
' ючестве режимов доступа и с п о л ь з у ю т с я с л е д у ю щ и е р е SENERIC^READ — ф а й л о т к р ы в а е т с я д л я ч т е н и я ; GENEфайл открывается д л я з а п и с и . О б а р е ж и м а м о г у т 339
б ы т ь з а д а н ы о д н о в р е м е н н о , в э т о м с л у ч а е о н и з а д а ю т с я так: GENERIC
READ | G E N E R I C W R I T E . В к а ч е с т в е р е ж и м о в с о в м е с т н о г о д о с т у п а использукл я
следующие могут
FILESHAREREAD
—
другие
приложения
FILE_SHARE_WRITE
—
другие
приложения
режимы:
читать
файл;
м о г у т п и с а т ь в ф а й л ; FILE
SHARE
DELETE — д р у г и е приложения
м о г у т у д а л я т ь ф а й л . Е с л и з а д а н 0 , т о с о в м е с т н ы й доступ к файлу н е д о п у с т и м , т . е . п о п ы т к а о т к р ы т ь д а н н ы й ф а й л д а ж е для про с м о т р а п р и в о д и т к о ш и б к е д о с т у п а . Р е к о м е н д у е т с я использовав FILE_SHARE_READ
для
облегчения
отладки
приложения.
А т р и б у т ы б е з о п а с н о с т и и с п о л ь з у ю т с я , е с л и необходимо защ и т и т ь ф а й л о т н е с а н к ц и о н и р о в а н н о г о д о с т у п а . В данном
KVJK*
м е т о д ы з а щ и т ы ф а й л о в н е р а с с м а т р и в а ю т с я . Е с л и специальны с р е д с т в а з а щ и т ы ф а й л о в н е т р е б у ю т с я , т о э т о т п а р а м е т р устанавливается равным 0. Р е ж и м ы о т к р ы т и я ф а й л а о п р е д е л я ю т , в к а к о м случае ф е • м о ж е т б ы т ь с о з д а н и л и о т к р ы т . Р е ж и м ы CREATE ... испольт ю т с я п р и с о з д а н и и н о в о г о ф а й л а и р а з л и ч а ю т с я в зависимое о т т о г о , ч т о д е л а т ь , е с л и ф а й л с т а к и м и м е н е м у ж е существ - < г Р е ж и м CREATE
NEW о з н а ч а е т , ч т о ф а й л с о з д а е т с я только в ш м
с л у ч а е , е с л и т а к о г о ф а й л а н е т . Р е ж и м CREATE_ALWAYS означ. ет, ч т о ф а й л с о з д а е т с я в л ю б о м с л у ч а е з а н о в о , независимо от то с у щ е с т в о в а л э т о т ф а й л и л и н е т . Р е ж и м OPEN_... и с п о л ь з у е т с я i : i о т к р ы т и я с у щ е с т в у ю щ и х и с о з д а н и я н о в ы х ф а й л о в . OPENJEXii TING и с п о л ь з у е т с я д л я о т к р ы т и я с у щ е с т в у ю щ и х ф а й л о в . Режим OPEN_ALWAYS
и с п о л ь з у е т с я и д л я о т к р ы т и я существующих, н
для создания новых файлов.
Режим
TRUNCATE_EXISTING таг
и с п о л ь з у е т с я д л я о т к р ы т и я ф а й л о в , н е з а в и с и м о о т и х существо в а н и я . С у щ е с т в у ю щ и е ф а й л ы у с е к а ю т с я д о н у л е в о г о размер П а р а м е т р ф л а г о в и а т р и б у т о в о п р е д е л я е т , п р е ж д е вег а т р и б у т ы ф а й л а п р и с о з д а н и и н о в о г о ф а й л а . В к а ч е с т в е атрнб тов м о ж н о задать такие атрибуты:
FILE_ATTRIBUTE
ARCHIVE
а р х и в н ы й ф а й л , т . е . п р и р е з е р в н о м к о п и р о в а н и и этот файт б д е т с к о п и р о в а н и э т о т ф л а г б у д е т с б р о ш е н д о т е х п о р , пока фай1 не
FILE_ATTRIBUTE_COMPRESSED
модифицируется.
-
фаг"
с ж а т . А т р и б у т и м е е т с м ы с л з а д а в а т ь , е с л и ф а й л о в а я система п держивает
этот
атрибут
FILE_ATTRIBUTE_HIDDEN
(NTFS). FILE
и
FILE
ATTRIBUTE
READ0NLУ,
ATTRIBUTESYSTEM
-то:
к о д л я ч т е н и я , с к р ы т ы й и с и с т е м н ы й ф а й л ы , соответств< FILE_ATTRIBUTE_TEMPORARY
—
используется
для
задания
м е н н о г о ф а й л а . Т а к о й ф а й л и с п о л ь з у е т с я д л я х р а н е н и я пром 340
вр<
х данных. После з а к р ы т и я о н о б ы ч н о у н и ч т о ж а е т с я . С и с т е м а иможности х р а н и т д а н н ы е э т о г о ф а й л а в п а м я т и . В к а ч е с т в е гов
используются
следующие
FILE_FLAG_OVER-
флаги.
~ D — используется д л я з а д а н и я а с и н х р о н н о г о р е ж и м а д о с т у файлу (сж.
8.9.3).
FILE_FLAG_WRITE_THROUGH
—
использу-
,ешзаписи ф а й л а о б р а б а т ы в а ю т с я с т р о г о п о с л е д о в а т е л ь н о . н случае О С п р и з а п р о с е о б р а б а т ы в а е т б л о к и м а к с и м а л ь н о жной
длины.
FlLEJFLAG_NOJBUFFER!NG
Флаг
использу-
I если для ввода-вывода не и с п о л ь з у е т с я б у ф е р . В э т о м с л у ч а е : р области п а м я т и , к у д а ч и т а ю т с я д а н н ы е , д о л ж е н б ы т ь к р а размеру сектора. А д р е с о б л а с т и п а м я т и д о л ж е н б ы т ь к р а т е н у сектора. Д л я о п р е д е л е н и я р а з м е р а с е к т о р а и с п о л ь з у е т с я кияGetDiskFreeSpace
(см.
8.8.5).
Параметр hTemplateFile з а д а е т д е с к р и п т о р с р е ж и м о м д о с т у KERIC READ к ф а й л у - ш а б л о н у . А т р и б у т ы э т о г о ф а й л а и с тся для с о з д а в а е м о г о ф а й л а . Э т о т п а р а м е т р д о л ж е н б ы т ь аОдля WINDOWS 9 5 . Функция возвращает д е с к р и п т о р ф а й л а п р и б л а г о п о л у ч н о м евии. Дескриптор з а д а е т у к а з а т е л ь н а и н ф о р м а ц и ю о ф а й бласти памяти я д р а . В с л у ч а е о ш и б к и ф у н к ц и я в о з в р а щ а е т JDHANDLE_VALUE. Функция CloseHandle Используется д л я о с в о б о ж д е н и я п а м я т и я д р а . Н е о б х о д и м о -ельно освобождать п а м я т ь с р а з у п о с л е т о г о , к а к з а к о н ч е н а с файлом. BOOL CloseHandle) HANDLE h O b j e c t ); rICbject — дескриптор ф а й л а , к о т о р ы й о с в о б о ж д а е т с я . Фшция возвращает « И с т и н у » , е с л и з а в е р ш и л а с ь б л а г о п о .и «Ложь» в случае о ш и б к и . 8.9.2. Синхронный ввод-вывод Функции ReodFile, WriteFile iOOL ReadFile( HANDLE hFile, IMIDIpBuffer, DWORD nNumberOfBytesToRead, '.WORD IpNumberOfBytesRead, ^OVERLAPPED IpOverlapped
341
BOOL WriteFile( HANDLE hFile, LPCVOID IpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD IpNumberOfBytesWritten, LPOVERLAPPED IpOverlapped ); hFile — д е с к р и п т о р ф а й л а ; IpBuffer — а д р е с б у ф е р а , к у д а в в о д и т ь ( о т к у д а выводить) Давные; nNumberOfBytesToRead — к о л и ч е с т в о б а й т о в , которые надо обработать; IpNumberOfBytesRead — к о л и ч е с т в о б а й т о в , которые обра таны; IpOverlapped — и с п о л ь з у е т с я д л я а с и н х р о н н о г о ввода-вьл да, д л я синхронного равен О. Определение размера файла DWORD GetFileSize( HANDLE hFile, LPDWORD IpFileSizeHigh ); hFile — д е с к р и п т о р ф а й л а ; IpFileSizeHigh — р а з м е р ф а й л а ( с т а р ш а я часть). Может бь равна н у л ю , если р а з м е р ф а й л а м е н ь ш е , ч е м 232. Ф у н к ц и я в о з в р а щ а е т р а з м е р ф а й л а ( м л а д ш у ю часть). Пример использования функций. С о с т а в и т ь ф у н к ц и ю д л я к о п и р о в а н и я ф а й л а и главную п] грамму для ее проверки. Ф а й л File.h #ifndef FILE_H #define FILEH #include <windows.h> inline HANDLE CreateNewFile (LPCTSTR FileName) { HANDLE h = CreateFile (FileName, GENERIC WRITE, FILE SHAREREAD, О, С REA TE_ NEW, 0, 0); return h;
} inline HANDLE CreateAlwaysFile (LPCTSTR FileName) { 342
HANDLEh = CreateFile (FileName, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0); return h;
itie HANDLE OpenFileForRead (LPCTSTR FileName) HANDLE h = CreateFile (FileName, GENERIC^ READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); return hi;
ieHANDLE OpenFileForReadAndWrite (LPCTSTR FileName) HANDLE h = CreateFile (FileName, GENERIC_READ\ GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0,0); return h;
«Idif •liiCopyFile.h
•••dude "file.h" • fjde<stdio.h> v CopyFHe (LPCTSTR src, LPCTSTR dest) HANDLE hSrc = INVALID_HANDLE_VALUE; HANDLE hDest = INVALID^ HA NDLE_ VALUE; PBYTEpMem = 0; boot b = tnie; J4 I hSrc = OpenFileForRead (src); if(hSrc == INVALID_HANDLE_VALUE) return false; hDest = CreateAlwaysFile (dest); if (hDest == INVALID_HANDLE_VALUE) return false; DWORD dwSize; dwSize = GetFileSize (hSrc, 0); pMem = new BYTE[dwSize]; iffpMem == 0) return false; DWORD dwCount; b = ReadFile (hSrc, pMem, dwSize, &dwCount, 0); if(lb) return to; 343
}
Ь = WriteFile (hDest, pMem, dwSize, &dwCount, Oj if (lb) return b; finally
{
}
if (hSrc != INVALID HANDLE VALUE) CloseHandle (hSrc); if (hDest 1= INVALID_HANDLE_VALUE) CloseHandle (hDest); if(pMem) delete[]pMem;
return b;
}
int main ()
{
}
boo/ b = CopyFile ("CopyFile.cpp", "CopyFile.bak"); if (b) pnntf ("CopyFile — OK\n"), else printf ("CopyFile — Error\n"); return 0;
Функции для поиска файлов Э т а г р у п п а ф у н к ц и й п о з в о л я е т в ы п о л н я т ь поиск файлов л и м е н и в с о о т в е т с т в и и с з а д а н н ы м ш а б л о н о м . В шаблоне можно а д а в а т ь с л е д у ю щ и е с и м в о л ы : ? — о з н а ч а е т , ч т о в данной позица м о ж е т б ы т ь л ю б о й о д и н с и м в о л . * — о з н а ч а е т , что вместо даа_ р( с и м в о л а м о ж е т б ы т ь л ю б а я п о с л е д о в а т е л ь н о с т ь символов, i к ч и с л е и п у с т а я . В с е о с т а л ь н ы е с и м в о л ы р а с с м а т р и в а ю т с я кикобь. н ы е с и м в о л ы . О н и д о л ж н ы п р и с у т с т в о в а т ь в и м е н и файла, кот*., w у д о в л е т в о р я е т ш а б л о н у . Н а п р и м е р , д л я з а д а н и я всех файлов, ш и р е н и е к о т о р ы х р а в н о С и л и С Р Р д о л ж е н б ы т ь задан шаблон *.ГЗ а м е т и м , ч т о д а н н о м у ш а б л о н у у д о в л е т в о р я ю т ф а й л ы с произвол н ы м и м е н е м и р а с ш и р е н и е м , к о т о р о е н а ч и н а е т с я с буквы С. Функция
FindFirstFile.
HANDLE FindFirstFile( LPCTSTR IpFileName, LPWIN32_FIND_ DATA
pFindFileData
); где: IpFileName — и м я ш а б л о н а д л я п о и с к а ф а й л а ; pFindFileData — а д р е с с т р у к т у р ы с и н ф о р м а ц и е й о найд -• н о м ф а й л е , е с л и э т о т ф а й л н а й д е н . С т р у к т у р а этой информап определена ниже. 344
Функция возвращает д е с к р и п т о р д л я о б л а с т и п а м я т и я д р а , зрой находится и н ф о р м а ц и я о н а й д е н н о м ф а й л е . Е с л и н е т ни ia, удовлетворяющего з а д а н н о м у ш а б л о н у , т о ф у н к ввращает INVALIDHANDLEVALUE. Структура информации о ф а й л е : typedefstruct _ WIN32_ FIND_ DATA { DWORD dwFileAtthbutes; FILETIf.'E f'CreationTime, ftLastAccessTime, ftLastWriteTime; DWORD nFileSizeHigh, nFileSizeLow; WORDdwReservedO, dwReservedl; TCHAR cFileName [MAX_PATH], cAlternateFileName [14]; W№_FIND_DATA, "PWIN32 FIND_ DA ТА; Поле dv/FiteAttributes — о п р е д е л я е т а т р и б у т ы ф а й л а ( о с н о в I атрибутами я в л я ю т с я FiLEA TTRIBUTEARCHIVE, FILE_ MUTE_DlRECTORY, FILE_ATTRIBUTE_ENCRYPTED, MTTRIBUTE_HIDDEN, FILE A TTRIBUTENORMAL, FILE_ WTE_READONLY, FILE_ATTRIBUTE_SYSTEM). HmftCreationTirne, ftLastAccessTime, ftLastWriteTime — o n p e -явременные метки ф а й л а , а и м е н н о в р е м я с о з д а н и я , в р е м я даего доступа и п о с л е д н е й з а п и с и в ф а й л . З а м е т и м , ч т о не д о в ы е системы п о з в о л я ю т и с п о л ь з о в а т ь в с е 3 м е т к и в р е м е • 'ак, файловая система т и п а F A T и с п о л ь з у е т т о л ь к о в р е м я п о "и записи в файл. М е т к и в р е м е н и з а д а ю т с я с п о м о щ ь ю т и п а |Е Тип FILETIME з а д а е т с я с т р у к т у р о й : tyedef struct _FILETIME { "WORD dwLowDateTime; 1.W0RD dwHighDateTime; FILETIME,'PFILET/ME; «задания используется 6 4 б и т а , к о т о р ы е о п р е д е л я ю т к о л и оЮОнаносекундных и н т е р в а л о в , к о т о р ы е п р о ш л и с 1 я н в а • !'А1годадо данного м о м е н т а в р е м е н и . Н и ж е п о к а з а н о , к а к э т о (привести к более у д о б н о м у в р е м е н и , в т о м ч и с л е с у ч е т о м лото часового пояса. >1я nFileSizeHigh, nFileSizeLow о п р е д е л я ю т 6 4 - б и т н о е з н а мя размера файла. Т а к и м о б р а з о м , ф у н к ц и ю FindFirstFile •использовать для о п р е д е л е н и я р а з м е р а ф а й л а в м е с т о ф у н к iSASize, причем в этом с л у ч а е о т к р ы в а т ь ф а й л н е н а д о . 7mcFileName[MAX_PATH], cAlternateFileName[14] опреде-вмяфайла: обычное и к о р о т к о е в ф о р м а т е 8 . 3 , к о т о р ы й о з н а 345
ч а е т , ч т о 8 с и м в о л о в о т в о д и т с я д л я и м е н и , 3 — д л я расширения и 2 символа в конце — нулевые. В о б щ е м с л у ч а е в к а т а л о г е м о ж е т б ы т ь н е с к о л ь к о файлов, у д о в л е т в о р я ю щ и х з а д а н н о м у ш а б л о н у . Д л я н а х о ж д е н и я остальн ы х ф а й л о в , у д о в л е т в о р я ю щ и х ш а б л о н у , и с п о л ь з у е т с я функция FindNextFile. Функция FindNextFile. BOOL FindNextFile ( HANDLE hFindFile, LPWIN32_ FIND_ DA ТА IpFindFileData
); Параметры: hFindFile — д е с к р и п т о р , к о т о р ы й в о з в р а т и л а функция FindFirstFile; IpFindFileData — а д р е с с т р у к т у р ы с д а н н ы м и о текущем ле, удовлетворяющем заданному шаблону. Ф у н к ц и я в о з в р а щ а е т з н а ч е н и е TRUE, е с л и ф а й л с заданным ш а б л о н о м н а й д е н , в п р о т и в н о м с л у ч а е ф у н к ц и я возвращает ч е н и е FALSE. Д л я о с в о б о ж д е н и я п а м я т и я д р а , з а н я т о й информацией ) ф а й л е , и с п о л ь з у е т с я ф у н к ц и я FindClose: BOOL FindClose(HANDLE hFindFile). Э т а ф у н к ц и я з а в е р ш а е т с я н е б л а г о п о л у ч н о , если выг н я е т с я п о п ы т к а о с в о б о ж д е н и я п а м я т и , к о т о р а я н е выделялась. Р а с с м о т р и м б о л е е п о д р о б н о т и п FILETIME и его использован и е п р и с о с т а в л е н и и п р о г р а м м . Н а п о м и н а е м , ч т о это 64-бт. ч и с л о , о п р е д е л я ю щ е е к о л и ч е с т в о е д и н и ц в р е м е н и , равных 1 0 к о т о р ы е п р о ш л и с 0 1 . 0 1 . 1 6 0 1 г о д а д о з а д а н н о г о момента времен! с у ч е т о м н у л е в о г о ч а с о в о г о п о я с а . Д л я п р и в е д е н и я этого временив с о о т в е т с т в и е с л о к а л ь н ы м ч а с о в ы м п о я с о м и с п о л ь з у е т с я функция File Time ToLocalFile Time. BOOL FileTimeToLocalFileTime ( const FILETIME* IpFileTime. LPFILETIME IpLocalFileTime
); В э т о й ф у н к ц и и IpFileTime о п р е д е л я е т в р е м я д л я 0 часовог п о я с а , IpLocalFileTime — в р е м я д л я л о к а л ь н о г о часового пояса. Д л я о п р е д е л е н и я в р е м е н и в е с т е с т в е н н о м формате по фор» т у FILETIME, и с п о л ь з у е т с я ф у н к ц и я FileTimeToSystemTime. 346
«OOL FileTimeToSystemTime ( const FILETIME * IpFileTime, LPSYSTEMTIME IpSystemTime
1'л;ультат преобразования з а п и с ы в а е т с я в с т р у к т у р у т и п а TIME: "Mdefstruct_SYSTEMTIME { tiORDwYear, wMcnth, wDayOfWeek, wDay; WORD wHour, wMinute, wSecond, wMilliseconds; SYSTEMTIME,'PSYSTEMTIME; цро| поля wYear, wMonth, wDayOfWeek, wDay о п р е д е л я ю т [ «сяц, день недели и д е н ь , с о о т в е т с т в е н н о , а п о л я wHour, te, wSecond, wMilliseconds — ч а с , м и н у т у , с е к у н д у и м и л л и •;f, соответственно. Для обратного преобразования и с п о л ь з у е т с я ф у н к ц и я SystemтШеТт: ?OOL SystemTimeToFileTimef const SYSTEMTIME* IpSystemTime, LPFILETIME IpFileTime
г
Еазяачение параметров э т о й ф у н к ц и и о ч е в и д н о . Примеры использования ф у н к ц и й п о и с к а . Пример 1. Найти в т е к у щ е м к а т а л о г е в с е ф а й л ы с р а с ш и • С, СРР и вывести д л я н и х в р е м я с о з д а н и я в ф о р м а т е 3 - hh::mm::ss. Include 'stdafx.h" include <mdows.h> • < elude mslng<mscoiiib.dll> . Jng namespace System; B| fmainO (' TCHAR tcTemplate[_MAX_PATH]; //Определение текущего каталога GetCurrentDirectory(sizeof (tcTemplate), tcTemplate); //Формирование шаблона Jcscat(tcTemplate, " U * c * " j ;
WIN32_FIND_DATA FindFileData; HANDLE hFile = FindFirstFile(tcTemplate,&FindFileData); 347
if (hFile {
==
INVALID_HANDLEJ/ALUE)
Console::WriteLine(S"Not return 1;
files");
} FILETIME CreateFileTime; SYSTEMTIME SystemTime; BOOL b; while (1) { // Определим время создания файла CreateFileTime = FindFileData.ftCreationTime; FileTimeToLocalFileTime(&CreateFileTime, &CreateFileTime), //Преобразуем его в нормальный формат FileTimeToSystemTimef&CreateFileTime, &SystemTmf // Вывод результата printf C%-40.40s %2.2d:%2.2d:%2.2d —" " :%2.2d::%2.2d::%2.2d\n", FindFileData.cFileName, SystemTime. wYear, SystemTime. wMonth, SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute. SystemTime. wSecond); //Нахождение очередного файла no заданному //шаблону b = FindNextFilefhFile, if (lb) break;
&FindFileData);
} }
FindClose(hFile); return 0;
В э т о м п р и м е р е д л я н а х о ж д е н и я т е к у щ е г о к а т а л о г а используется ф у н к ц и я GetCurrentDirectory. Пример результата работы программы: A s s e m b l y l n f о. срр 2004:12:04 — :16::54::27 FindFiles.cpp 2004:12:04 — :16::54::27 stdafx.cpp 2004:12:04 — :16::54::27 И з э т о г о п р и м е р а в и д н о , ч т о в т е к у щ е м к а т а л о г е расположено 3 ф а й л а , у д о в л е т в о р я ю щ и х з а д а н н о м у ш а б л о н у , и время создания для этих файлов. П р и м е р 2 . В ы в е с т и и м е н а в с е х ф а й л о в т е к у щ е г о каталога, в том ч и с л е и ф а й л о в во всех в л о ж е н н ы х каталогах. ttinclude"stdafx.h" ttinclude <windows.h> #using <mscodib.dll> 348
inamespace System; JtiMDirs () _FIND_DATA FindFileData; WDLEhFile = FindFirstFile ("*.*", &FindFileData); ЦП - INVALID_HANDLE_VALUE) return;
H(FmdFileData.cFileName[0] =='.') continue; if((FindFileData.dwFileAttributes & FILEATTRIBUTEDIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
{ SetCurrentDirectory FindDirs ();
(FindFileData.cFileName);
else
printf ("%s\n", FindFileData. cFileName); ) while (b = FindNextFile (hFile, &FindFileData)); FindC/ose (hFile); mt_tirain() char buf[MAX__PA THJ; I
GetCurrentDirectory (sizeof (buf), buf); FindDirs ();
SetCurrentDirectory (buf); return 0; 8.9.3. Асинхронный ввод-вывод Асинхронный в в о д - в ы в о д п о з в о л я е т параллельно выполкть ввод-вывод данных и в ы ч и с л е н и я . Ф у н к ц и и в в о д а - в ы в о д а ; !&ляют задать этот р е ж и м (см. ф у н к ц и и ReadFile, WriteFile). h i использовании этого р е ж и м а н е о б х о д и м о р е ш и т ь п р о б л е м у (юсроншции операции з а в е р ш е н и я в в о д а - в ы в о д а и п р о д о л ж е ю вычислений в заданной т о ч к е п р о г р а м м ы . З д е с ь б у д у т р а с тлены способы р е ш е н и я э т о й п р о б л е м ы . С н а ч а л а р а с с м о т р и м -:пурутвпа OVERLAPPED, а д р е с к о т о р о й з а д а е т с я в ф у н к ц и и ц-fife, WriteFile (последний п а р а м е т р ) . 349
typedefstruct OVERLAPPED { ULONCPTR Internal; ULONCPTR InternalHigh. DWORD Offset; DWORD OffsetHigh: HANDLE hEvent; } OVERLAPPED: Поля структуры: Internal — к о д о ш и б к и ; InternalHigh — к о л и ч е с т в о п е р е д а н н ы х б а й т о в : Offset — н а ч а л ь н а я п о з и ц и я в ф а й л е п р и обращении к в я у ( м л а д ш а я часть); OffsetHigh — - н а ч а л ь н а я п о з и ц и я в ф а й л е п р и обращеиип к нему ( с т а р ш а я часть); hEvent — о п и с а т е л ь с о б ы т и я и л и д а н н ы е . З а м е т и м о с н о в н ы е о с о б е н н о с т и и с п о л ь з о в а н и я ясинхрон ,л "> ввода-вывода. Т е к у щ е е с м е щ е н и е в ф а й л е д л я н а ч а л а н о в о й операция д с * но устанавливаться заново для каждой операции. П е р е х о д н а о ч е р е д н о й о п е р а т о р п р о г р а м м ы выполняй л с р а з у п о с л е в ы з о в а ф у н к ц и и в в о д а - в ы в о д а и л и п о с л е выполнен! [ о п е р а ц и и . О С в ы п о л н я е т о п е р а ц и ю с и н х р о н н о , е с л и даввые. т о р ы е д о л ж н ы б ы т ь п р о ч и т а н ы , ф а к т и ч е с к и н а х о д я т с я в буфетФ у н к ц и и ReadFile, WriteFile в о з в р а щ а ю т TRUE, если защ» п о л н я е т с я с и н х р о н н о , и FALSE, е с л и з а п р о с выполняется ва »• | хронно. Чтобы о п р е д е л и т ь д е й с т в и т е л ь н у ю причин} FALSE, н е о б х о д и м о в ы з в а т ь ф у н к ц и ю GetLastError. которая щ в р а щ а е т ERROR_IO_PENDING, е с л и в а п р о с п о с т а в л е н в очерел к устройству вводп-вывода_
B03ip»u |
О п е р а ц и и в в о д е - в ы в о д е ф а к т и ч е с к и м о г у т выполняться я в т о м п о р я д к е , а к о т о р о м о н и в ы з ы в а ю т с я в программе. Нчере* н о с т ь о п е р а ц и й о п р е д е л я е т с я д р а й в е р о м , упорядочивяющки и с у ч е т о м м а к с и м а л ь н о й п р о и з в о д и т е л ь н о с т и устройства. С т р у к т у р а т и п а OVERLAPPED и б у ф е р , используемы! № в в о д а в ы в о д а д е н н ы х , н е д о л ж н ы у н и ч т о ж а т ь с я д о завершен»ввода-выводаJ Н и ж е б у д у т р а с с м о т р е н ы с п о с о б ы у в е д о м л е н и я о зав а » н и в о п е р а ц и и в в о д а - в ы в о д а . Д а н н о е у в е д о м л е н и е необходимо i того, чтобы использовать д а н н ы е , к о т о р ы е прочитаны с I.» ства ввода-вывода и л и в ы в е д е н ы на другое устройство. 350
эдомления о завершении в в о д а - в ы в о д а
Взависимости от способа у в е д о м л е н и я о н и д е л я т с я на 4 к л а с с а . 1. Сигнализация о б ъ е к т а я д р а , к о т о р ы й у п р а в л я е т у с т р о й !, Для файла таким о б ъ е к т о м я в л я е т с я д е с к р и п т о р ф а й л а , и о дескриптор ф а й л а в ы с т у п а е т к а к а р г у м е н т ф у н к ц и и gleObject. В этом с л у ч а е у в е д о м л е н и е с о д е р ж и т и н ф о р 1 только о том, д л я к а к о г о ф а й л а з а в е р ш и л а с ь о п е р а ц и я , ну, если для файла с ф о р м и р о в а н о д в а з а п р о с а д л я в в о д а а, то по уведомлению б у д е т н е и з в е с т н о , к а к а я о п е р а ц и я г е н а конкретно. Д а н н ы й м е т о д м о ж н о п р и м е н я т ь т о л ь к о • случае, если одновременно д л я ф а й л а в ы п о л н я е т с я т о л ь к о Иерация. 2. Сигнализация о б ъ е к т а я д р а , у п р а в л я ю щ е г о с о б ы т и я м и , ктуре OVERLAPPED е с т ь д е с к р и п т о р с о б ы т и я , к о т о р о е использовать для у в е д о м л е н и я о з а в е р ш е н и и к о н к р е т н о й д а . Перед в ы п о л н е н и е м к а ж д о й о п е р а ц и и в в о д а - в ы в о д а Ш событие, с о о т в е т с т в у ю щ е е д а н н о й о п е р а ц и и ( ф у н к ц и я ivenf). Для обработки у в е д о м л е н и й о з а в е р ш е н и и и с п о л ь • функция WatForMultipleObjects, по к о т о р о й м о ж н о о п р е д е , какое конкретное с о б ы т и е п р о и з о ш л о . Д а н н у ю ф у н к ц и ю ] «заставить» ж д а т ь з а в е р ш е н и я в с е х с о б ы т и й . П о с л е з а вия операции в в о д а - в ы в о д а м о ж н о н а п р я м у ю п р о в е р и т ь трата (поле Internal с т р у к т у р ы OVERLAPPED) и к о л и ч е с т в о лных байтов (поле InternalHigh с т р у к т у р ы OVERLAPPED). ) получить д о п о л н и т е л ь н у ю и н ф о р м а ц и ю о з а в е р ш е н н о й .ии ввода-вьшода. Д л я э т и х ц е л е й и с п о л ь з у е т с я ф у н к ц и я : Ш GetOverlappedResult ( HANDLE hFile,
IPOVERLAPPED IpOverlapped, LPDWORD IpNumberOfBytesTransferred, BOOLbWait
file — дескриптор ф а й л а ; tapped— структура с и н ф о р м а ц и е й о з а п р о с е в в о д а - в ы \berOfBytesTransferred — к о л и ч е с т в о п е р е д а н н ы х б а й bWeif - если параметр р а в е н TRUE, то ф у н к ц и я не з а в е р ш а вших пор, пока о п е р а ц и я в в о д а - в ы в о д а не з а в е р ш е н а . Е с л и 351
з а д а н о FALSE, т о , е с л и о п е р а ц и я н е з а в е р ш е н а , one в о з в р а т а FALSE. и функция GetLastError в о з в р а щ а е т ERRORJOJNCU? LETE. О п о в е с т и т е л ь н ы й в в о д - в ы в о д . С у т ь оповестительного I » д а - в ы в о д о с о с т о и т в т о м . ч т о в ф у н к ц и и ввода-вывода . -а» у к а з а т ь а д р е с ф у н к ц и и , к о т о р а я м о ж е т б ы т ь вызвана • л п в з а в е р ш е н и я о п е р а ц и и ( a p p l i c a t i o n - d e f i n e d c o m p l e t i o n пзаММ А Р С ) . Д л я э т о г о в м е с т о ф у н к ц и й ReadFile, WriteFile ИСЕОЛ! . И ф у н к ц и и ReedFileEx, WriteFileEx. Р а с с м о т р и м в качестве функцию ReadFiteEx: BOOL ReadFileExf HANDLE hFile, LPVOID IpBuffer. DWORD nNumberOfBytesToRead. L POVERLAPPED IpOvedapped. LPOVERLAPPED COMPLETION ROUTINE IpCcmptetionRa •*
):
В с п и с к е п а р а м е т р о в э т о й ф у н к ц и и , по с р а в н е н и ю с i 1 т р а м и ф у н к ц и и ReadFile, д о п о л н и т е л ь н ы й п а р а м е т р IpCompt • Routine о п р е д е л я е т а д р е с ф у н к ц и и , к о т о р а я б у д е т постен в о ч е р е д ь ф у н к ц и й о б р а т н о г о в ы з о в а п о т о к у , делающий м ввода-вывода. Кроме того, ф у н к ц н я не возвращает колм 1 б а й т о в , к о т о р о е б ы л о п р о ч и т е п о . Э т о к о л и ч е с т в о байтов моя б ы т ь п о л у ч е н о ф у н к ц и е й IpCompletionRoutine. Данная имеет заголовок:
где:
VOID WINAPI CompletionRoutine (DWORD dwError. DWORD dwNum-Bytes. OVERLAPPED 'ov): dwError — к о д о ш и б к и ;
dwNumBytes — к о л и ч е с т в о п е р е д а н н ы х Сайтов; ov - а д р е с с т р у к т у р ы ш п а OVERLAPPED. З а м е т и м , ч т о в э т о м с л у ч а е д р а й в е р н е использует coffin и з с т р у к т у р ы OVERLAPPED. Е щ е р а з о б р а щ а е м в а ш е и н я ш на то, ч т о ф у н к ц и я с т а в и т с я в о ч е р е д ь п о т о к у , но не яыо< Ц е т е я а в т о м а т и ч е с к и в с в я з и с т е м , ч т о в э т о в р е м я DOTOK кожа б ы т ь з а н я т ч е м - т о д р у г и м . Ч т о б ы э т у ф у н к ц и ю выполнят!. • т о к в т о т м о м е н т , к о г д а е м у н у ж н ы в в е д е н н ы е данные, доля I п е р е в е с т и с е б я в р е ж и м о ж и д а н и я о п о в е щ е н и я . Д л я пе • • J в с о с т о я н и е о ж и д а н и я о п о в е щ е н и я и с п о л ь з у е т с я одни из t "1 ций: SleapEx, WaitForSingleObjectEx, WaitForMultipleObjecisF SignalObjectAndWait. В э т и х ф у н к ц и я х п о с л е д н и м параметр.*
: «невский параметр fAlertable. Е с л и з н а ч е н и е э т о г о п а р а шно TRUE, то поток п е р е в о д и т с е б я в с о с т о я н и е о ж и д а н и я вшия. Для перевода в с о с т о я н и е о п о в е щ е н и я м о ж н о т а к ж е ать функцию MsgWaitForMultipleObjectEx, в которой
Р
араметра dwFlags з а д а е т с я ф л а г MWMO ALERTABLE. случае при переходе п о т о к а в р е ж и м о ж и д а н и я о п о в е щ е юверяет очередь ф у н к ц и й о б р а т н о г о в ы з о в а , и , е с л и о н а я, эта функция в ы з ы в а е т с я п р и о с т а н о в л е н н ы м п о т о к о м , т о с к и поток н е п р и о с т а н а в л и в а е т с в о ю р а б о т у . Р а б о т а бновляется в с и н х р о н н о м р е ж и м е п о с л е в ы п о л н е н и я хщш очереди. Все ф у н к ц и и о ж и д а н и я в о з в р а щ а ю т з н а IVIMTJOJCOMPLETION, е с л и о б р а б о т а н а х о т я б ы о д н а з а 5 очереди (т.е. очередь б ы л а не п у с т а я ) . Е с л и в о з в р а щ а е т с я вчение, это означает, ч т о , н а п р и м е р , и с т е к к в а н т в р е м е 1НЫЙ в функции. остаток этого м е т о д а — н е о б х о д и м о с т ь с о з д а н и я д о льной функции, к о т о р а я в ы з ы в а е т с я . Т а к к а к з а р а н е е •тво, когда эта ф у н к ц и я б у д е т в ы з в а н а , д л я о б е с п е ч е н и я >сти выполнения в н е й к а к о г о - т о п о л е з н о г о к о д а н е о б х о вать некоторые д а н н ы е д л я н е е в о в н е ш н и х п е р е м е н н ы х , втого, очередь создается д л я п о т о к а , и е с л и п о т о к п о с л а л ькозапросов на в ы п о л н е н и е о п е р а ц и и в в о д а - в ы в о д а , то в ы ; функции завершения э т и х о п е р а ц и й т а к ж е д о л ж е н т о т к, хотя другие потоки в э т о в р е м я м о г у т п р о с т а и в а т ь — э т о i тщественный н е д о с т а т о к о п о в е с т и т е л ь н о г о в в о д а - в ы в о гам, что сам по себе м е х а н и з м и с п о л ь з о в а н и я ф у н к ц и й з вызова является п о л е з н ы м , б о л е е т о г о ОС W I N D O W S iei приложению з а п и с а т ь в о ч е р е д ь А Р С з а д а н н у ю ф у н к Рксмотрим эту ф у н к ц и ю : '.MRDQueueUserAPC PAPCFUNC pfnAPC, HANDLE hThread, ULONG PTRdwData
iHPC — адрес ф у н к ц и и , з а п и с ы в а е м о й в о ч е р е д ь п о т о к а . j-я должна иметь з а г о л о в о к : VOID CALLBACK APCProc tG__PTR dwParam), в к о т о р о м dwParam о п р е д е л я е т а д р е с п а I, передающегося ф у н к ц и и о б р а т н о г о в ы з о в а ; 353
(
hThread — д е с к р и п т о р п о т о к а , в о ч е р е д ь которого ш веется ф у н к ц и я обратного вызова. П о т о к м о ж е т прав • текущему или другому процессу; dwData — а д р е с п а р а м е т р а , к о т о р ы й п е р е д а е т с я ф у н к г а в * ратного вызова. Ф у н к ц и я в о з в р а щ а е т н е н у л е в о е з н а ч е н и е п р и благоп л я т з а в е р ш е н и и и О в с т у ч а е о ш и б к и . Ф у н к ц и ю QueveUserAPC • использовать д л я р а з б л о к и р о в а н и я п о т о к а , который жди т н о е с о б ы т и е . Р а с с м о т р и м , к а к э т о м о ж н о выполнитьпрактича П у с т ь п о т о к с д е с к р и п т о р о м hThreadl ж д е т з а в е р ш е н и я о ч т е н и я ф а й л а (SleepEx-..). П у с т ь э т о т п о т о к н а д о разблокируют Д л я э т о г о в о ч е р е д ь п о т о к а hThreadl з а п и ш е м ф у н к ц и ю , « ч н и ч е г о н е д е л а е т . Ф у н к ц и я SleepEx п р о в е р я е т очередь. Ткд о ч е р е д ь н е п у с т а я , э т а ф у н к ц и я в ы з ы в а е т с я , п о т о к раА*< руется. 3 . И с п о л ь з о в а н и е п о р т а в а в е р ш е н и я ввода-вывода. Совоеин н ы е в ы ч и с л и т е л ь н ы е с и с т е м ы о ч е н ь ч а с т о д о л ж н ы обра(ц м н о ж е с т в о з а п р о с о в . Э т о , п р е ж д е в с е г о , х а р а к т е р н о д л я i > аЛТ П о с л е д о в а т е л ь н а я о б р а б о т к а т а к и х в а п р о с о в н е обеспеч о б х о д и м у ю п р о и з в о д и т е л ь н о с т ь и п л о х о масштабируется у в е л и ч е н и я ч и с л я п р о ц е с с о р о в . Д л я о б е с п е ч е н и я ппрал о б р а б о т к и к а ж д о м у в а п р о с у с т а в и т с я в соответствие i п о т о к , в э т о м с л у ч а е у в е л и ч е н и е ч и с л а п р о ц е с с о р о в ув > п р о и з в о д и т е л ь н о с т ь В С . Д л я с о з д а н и я п о т о к о в н псррк.«и »-• м е ж д у п о т о к а м и в с л у ч а е , е с л и ч и с л о п о т о к о в б о л ь ш е чп« х ц е с с о р о в , т р е б у е т с я о п р е д е л е н н о е в р е м я . Х о т я э т о время т е л ь и о м е н ь ш е , ч е м п р и с о з д а н и и н о в ы х процессов, в яе • , с л у ч а я х т а к и е п о т е р и в р е м е н и н е д о п у с т и м ы - Д л я исключеиь» т е р ь в р е м е н и н а с о з д а н и е и п е р е к л ю ч е н и е м е ж д у потоками м м с о з д а т ь п о т о к и п р и и н и ц и а л и з а ц и и ОС, н а п р и м е р , д л я M.«J п р о ц е с с о р а ( п у л п о т о к о в ) . П р и с о з д а н и и у с т а н о в и т ь режим I д п н и я (см. 4 . 4 . 3 ) . З а к р е п и т ь к а ж д ы й п о т о к з а своим процес Д л я у п р а в л е н и я п у л о м п о т о к о в и с п о л ь з у е т с я порт завершил ввода-вывода. Порт завершения звода-вывода Д л я с о з д а н и я п о р т а и с п о л ь з у е т с я ф у н к ц и я Creafe/oConjifct ionPort: HANDLE CreateloCompMionPort ( HANDLE EileHandle. HANDLE ExistingCompIetiortPort 354
UL0NG_PTR CompletionKey, DWORD NumberOfConcurrentThreads 1
Список параметров э т о й ф у н к ц и и б у д е т р а с с м о т р е н п о с т е ;. по мере определения н а з н а ч е н и я д а н н о й ф у н к ц и и . П а р а 1 himberOfConcurrentThreads о п р е д е л я е т м а к с и м а л ь н о е к о л и (Iодновременно р а б о т а ю щ и х п о т о к о в ( р а з м е р п у л а п о т о к о в ) . I вот параметр равен 0, то к о л и ч е с т в о о д н о в р е м е н н о р а б о т а ю «потоков равно числу п р о ц е с с о р о в . П о э т о м у д л я с о з д а н и я п о р ааточно использовать ф у н к ц и ю , к о т о р а я п р е д л о ж е н а в [ 4 ] : •ШЕ CreateNew ComptetionPort( DWORD dwNumberOfConcurrentThreads)
1
return CreateloCompletionPort (INVALID_HANDLE_VALUE, 0, 0, NumberOfConcurrentThreads);
[ )1мее необходимо с в я з а т ь у с т р о й с т в а в в о д а - в ы в о д а с с о з »портом. Для о р г а н и з а ц и и э т о й с в я з и и с п о л ь з у е т с я ф у н к DLAssociateDeviceWithCompletionPort (HANDLE hCompPort, ЖЕ hDevice, DWORD dwCompKey){ HANDLE h = CreateloCompletionPort (hDevice, hCompPort, rtvCompKey, 0); return h == hCompPort; ",шим образом, п а р а м е т р FileHandle ф а к т и ч е с к и о п р е д е л я е т tip устройства, с в я з а н н о г о с с о з д а н н ы м п о р т о м в в о д а . В качестве у с т р о й с т в а м о ж е т б ы т ь з а д а н д е с к р и п т о р I и любого другого о б ъ е к т а , д л я к о т о р о г о о п р е д е л е н о п о tдескриптора типа HANDLE. К а ж д о м у у с т р о й с т в у с т а в и т с я тствие ключ з а в е р ш е н и я CompletionKey, к о т о р ы й и с гся по усмотрению п р о г р а м м и с т а ; ОС не р а б о т а е т с э т и м ром. Одному п о р т у м о г у т с о о т в е т с т в о в а т ь н е с к о л ь к о в, в этом случае ф у н к ц и ю AssociateDeviceWithComplet необходимо вызвать д л я к а ж д о г о у с т р о й с т в а о т д е л ь н о , выу порту ставит в с о о т в е т с т в и е м а с с и в с в я з а н н ы х с н и м тв. По завершении о п е р а ц и и а с и н х р о н н о г о в в о д а - в ы в о д а юйств, связанных с п о р т о м , и н ф о р м а ц и я об э т о й о п е р а г а с н в а е т с я в очередь э т о г о п о р т а . И н ф о р м а ц и я в к л ю ч а е т : 5исло переданных б а й т , з н а ч е н и е CompletionKey д л я э т о г о нива, адрес с о о т в е т с т в у ю щ е й с т р у к т у р ы OVERLAPPED (шбки. 355
П о с л е с о з д а н и я п о р т а з а в е р ш е н и я н е о б х о д и м о создать г : п о т о к о в . К а к б ы л о с к а з а н о в ы ш е , и д е а л ь н ы м с т о ч к и зренияпр и з в о д и т е л ь н о с т и я в л я е т с я в ы б о р ч и с л а п о т о к о в в пуле раввы_ к о л и ч е с т в у п р о ц е с с о р о в . А в т о р [ 4 ] п р е д л а г а е т в ы б и р а т ь это Ч№ 2 * ч и с л о п р о ц е с с о р о в . В с е п о т о к и в п у л е д о л ж н ы выполнять о и т е ж е д е й с т в и я . Э т о т п о т о к о б ы ч н о п р е д с т а в л я е т собой бескон н ы й ц и к л . В ц и к л е п о т о к п е р е в о д и т с е б я в р е ж и м ожидания J в е р ш е н и я о п е р а ц и и в в о д а - в ы в о д а с п о м о щ ь ю п о р т а завершим в в о д а - в ы в о д а . Д л я п е р е х о д а в р е ж и м о ж и д а н и я использу функция: BOOL
GetQueuedCompletionStatus ( HANDLE CompletionPort, LPDWORD IpNumberOfBytes, PULONG_PTR IpCompletionKey, LPOVERLAPPED* IpOverlapped, DWORD dwMilliseconds
}; где: CompletionPort — п о р т з а в е р ш е н и я , с о с т о я н и е которого я слеживается; IpNumberOfBytes — к о л и ч е с т в о б а й т , к о т о р о е передано в ош рации ввода-вывода (результат); IpCompletionKey — к л ю ч , к о т о р ы й с в я з а н с портом (сл. пр дущую функцию); IpOverlapped — а д р е с с т р у к т у р ы OVERLAPPED из запрс ввода-вывода; dwMilliseconds — в р е м я , в т е ч е н и е к о т о р о г о ждать заверс ние операции (тайм аут). Э т а ф у н к ц и я ф а к т и ч е с к и в ы п о л н я е т т у ж е роль, что $vi ц и я WaitForSingleObject, но и с п о л ь з у е т с я с п о р т а м и завершен1 П о э т о й ф у н к ц и и д л я з а д а н н о г о п о р т а з а н о с и т с я очередная заш в о ч е р е д ь п о т о к о в , ж д у щ и х з а в е р ш е н и я . К а к т о л ь к о появляе'ri и н ф о р м а ц и я о з а в е р ш е н и и о п е р а ц и и ( з а п и с ь в очереди завыш е н и я ) , О С а к т и в и з и р у е т р а б о т у п о т о к о в , к о т о р ы е ожидали операцию. Т а к и м о б р а з о м , в ы х о д и з о ж и д а н и я м о ж е т произойти I д в у м п р и ч и н а м : з а в е р ш и л а с ь о п е р а ц и я в в о д а - в ы в о д а или я т ш и л с я з а д а н н ы й и н т е р в а л в р е м е н и . Д л я о п р е д е л е н и я причта выхода м о ж н о использовать п р о г р а м м н ы й код: 356
Со:идание порта и связывание его с устройствами л* ,^Ожидание завершения операции ввода-вывода "WORD Member Of Bytes, dwTimeOut= 1000; .LONG ulCompletionKey; mLAPPED Overlapped; I0CL b = B00L GetQueuedCompletionStatus( CompletionPort, AdwNumberOfBytes, HulCompletionKey, Overlapped, dwTimeOut
I
Обработка ошибки WORD dwError = GetLastError ();
m
if(&Overlapped){ Сбой ввода-вывода. dwError— код ошибки } etsef if (dwError" \Л/А1Т_Т1МЕОиТ){Истекло время} else {Что-то со списком параметров функции GetQueuedCompletionStatus }
яметим, что п о т о к и , о ж и д а ю щ и е з а в е р ш е н и я о п е р а ц и и а, записываются в с т е к . П о с л е з а в е р ш е н и я о п е р а ц и и иыбираются из стека, п о э т о м у и с п о л ь з у е т с я д и с ц и п л и н а обния: последний в о ш е л , п е р в ы й о б с л у ж е н . К о л и ч е с т в о ев, которое будет и з в л е ч е н о из с т е к а , р а в н о м а к с и м а л ь н о м у V потоков, заданному п р и с о з д а н и и п о р т а в в о д а - в ы в о д а . В с е !, которые разблокируются, з а п и с ы в а ю т с я в с п и с о к р а з б л о ных потоков. В стеке з а б л о к и р о в а н н ы х п о т о к о в о с т а ю т с я •JKH, которые не могут б ы т ь р а з б л о к и р о в а н ы в с в я з и с о г р а «м на число одновременно в ы п о л н я е м ы х п о т о к о в . Е с л и из ч потоков, которые б ы л и р а з б л о к и р о в а н ы , о д и н из п о т о к о в •«{локируется в связи с о ч е р е д н ы м з а п р о с о м , о ч е р е д н о й п о т о к Врется из списка з а б л о к и р о в а н н ы х . Э т о т п о т о к р а з б л о к и р у | д а продолжения в ы п о л н е н и я . И м е н н о д л я э т о г о с о з д а е т с я лас потоков, готовых к в ы п о л н е н и ю . Пример. Составить п р о г р а м м у д л я к о п и р о в а н и я ф а й л а с о д |и устройства на другое, и с п о л ь з у я а с и н х р о н н ы й в в о д - в ы в о д fbrft завершения ввода-вывода. П р и к о п и р о в а н и и о п р е д е л и т ь p i кластеров файла. О п р е д е л и т ь к о л и ч е с т в о п о т о к о в , р а в н о е 357
П о с л е с о з д а н и я п о р т а з а в е р ш е н и я н е о б х о д и м о создать Е 1 п о т о к о в . К а к б ы л о с к а з а н о в ы ш е , и д е а л ь н ы м с т о ч к и зрения щ и з в о д и т е л ь н о с т и я в л я е т с я в ы б о р ч и с л а п о т о к о в в пуле раве к о л и ч е с т в у п р о ц е с с о р о в . А в т о р [ 4 ] п р е д л а г а е т в ы б и р а т ь это чш 2 * ч и с л о п р о ц е с с о р о в . В с е п о т о к и в п у л е д о л ж н ы выполнять о л и т е ж е д е й с т в и я . Э т о т п о т о к о б ы ч н о п р е д с т а в л я е т собой бескогу н ы й ц и к л . В ц и к л е п о т о к п е р е в о д и т с е б я в р е ж и м ожидания а в е р ш е н и я о п е р а ц и и в в о д а - в ы в о д а с п о м о щ ь ю п о р т а заверши и. i в в о д а - в ы в о д а . Д л я п е р е х о д а в р е ж и м о ж и д а н и я использус функция: BOOL
GetQueuedCompletionStatus ( HANDLE CompletionPort, LPDWORD IpNumberOfBytes, PULONG_PTR IpCompletionKey, LPOVERLAPPED* IpOverlapped. DWORD dwMilliseconds
}; где: CompletionPort — п о р т з а в е р ш е н и я , с о с т о я н и е которого": слеживается; IpNumberOfBytes — к о л и ч е с т в о б а й т , к о т о р о е передано в и рации ввода-вывода (результат); IpCompletionKey — к л ю ч , к о т о р ы й с в я з а н с портом (см. пр дущую функцию); IpOverlapped — а д р е с с т р у к т у р ы OVERLAPPED из запр" ввода-вывода; dwMilliseconds — в р е м я , в т е ч е н и е к о т о р о г о ж д а т ь заверь ние операции (тайм аут). Э т а ф у н к ц и я ф а к т и ч е с к и в ы п о л н я е т т у ж е роль, что 4 ' ц и я WaitForSingleObject, но и с п о л ь з у е т с я с п о р т а м и завершен П о э т о й ф у н к ц и и д л я з а д а н н о г о п о р т а з а н о с и т с я очередная зап" в о ч е р е д ь п о т о к о в , ж д у щ и х з а в е р ш е н и я . К а к т о л ь к о появляегг и н ф о р м а ц и я о з а в е р ш е н и и о п е р а ц и и ( з а п и с ь в очереди зе1*}> ш е н и я ) , О С а к т и в и з и р у е т р а б о т у п о т о к о в , к о т о р ы е ожидали операцию. Т а к и м о б р а з о м , в ы х о д и з о ж и д а н и я м о ж е т произойти д в у м п р и ч и н а м : з а в е р ш и л а с ь о п е р а ц и я в в о д а - в ы в о д а или 31 ш и л с я з а д а н н ы й и н т е р в а л в р е м е н и . Д л я о п р е д е л е н и я причш_ выхода м о ж н о использовать п р о г р а м м н ы й код: 358
даю 2 всех 8-байтных блоков файла. Неполный последний блок дополнить О (NTFS). В. Используя функцию GetLogicalDrives, определить число разделов винчестера. Реализовать эту функцию (см. пример 9). 16. Используя функцию GetVoluinelnforinatioii, определить файловуюсистему для разделов винчестера. Реализовать эту функцию (ся пример 9). !* Используя функцию GetDiskFreeSpace, определите свободное дисковое пространство для каждого раздела. Напишите алгоритм реализации этой функции для файловых систем типа FAT и NTFS. IJ. В чем различие между синхронным и а синхронным вводом-выводом, приведите пример, когда целесообразно использовать асинхронный ввод-вывод. D. Пусть необходимо прочесть файлы с CD и с жесткого диска. Напишите программу, используя синхронный и асинхронный ввод для чтения этих файлов. Сравните варианты по вычислительной сложности.
359
9. ДРАЙВЕРЫ
Цели изучения р а з д е л а : 1. Ознакомиться с этапами развития драйверов. 2. Изучить методы доступа к системному реестру 3. Выработать навыки практического использования функций дровера в пользовательских приложениях. 4. Рассмотреть структуру современных драйверов на примере 32-6л ных драйверов для W I N D O W S 2 0 0 0 . 5. Исследовать этапы создания и компоновки драйверов на конкр* ных примерах. 6. Освоить методы з а г р у з к и драйверов. Изучить динамическую 1 грузку. 7. Научиться практическому использованию служб.
9.1. Определение драйвера Д р а й в е р — э т о п р и л о ж е н и е , п р е д н а з н а ч е н н о е д л я изменения и д о б а в л е н и я ф у н к ц и й о п е р а ц и о н н о й с и с т е м ы , в т о м числе упр л е н и я в н е ш н и м и у с т р о й с т в а м и . М о ж н о н а п и с а т ь драйвер для р е ш е н и я о б ы ч н о й п о л ь з о в а т е л ь с к о й з а д а ч и , н о т а к к а к написяш™ д р а й в е р а и е г о к о м п и л я ц и я з н а ч и т е л ь н о с л о ж н е е , ч е м обычного п р и л о ж е н и я , а е г о в ы г р у з к а т р е б у е т с п е ц и а л ь н ы х у с и л и й , этот никогда не делают. Д а н н ы й р а з д е л я в л я е т с я о д н и м и з с а м ы х с л о ж н ы х в учебном п о с о б и и . Е г о с л е д у е т ч и т а т ь н е с к о л ь к о р а з , н е п ы т а я с ь все усвоип и п о н я т ь п р и п е р в о м ч т е н и и . В о в р е м я о д н о г о и з п е р в ы х чтений о б я з а т е л ь н о с л е д у е т в ы п о л н и т ь п р и м е р ы , п р и в е д е н н ы е в подр д е л е 9 . 4 , а з а т е м и в п о д р а з д е л е 9 . 6 . Д л я в ы п о л н е н и я пример п о д р а з д е л а 9 . 6 в а м п о т р е б у е т с я V i s u a l S t u d i o и Device D 360
ver КГГ
Затем при п о в т о р н ы х ч т е н и я х с н о в а о б р а щ а й т е с ь к п р и г ютех пор, пока о н и н е б у д у т д о к о н ц а п о н я т н ы . П о с л е д о лого изучения п р и в е д е н н ы х п р и м е р о в р а с с м о т р и т е х о т я я пример исходных к о д о в , п р и в е д е н н ы х в D D K .
9.2. История создания д р а й в е р о в 9.2.1. Использование п р о г р а м м у п р а в л е н и я вводом-выводом И р обеспечения в о з м о ж н о с т и п а р а л л е л ь н о г о в ы п о л н е н и я -д-вывода и о п е р а ц и й п р о ц е с с о р а к о м а н д ы в в о д а - в ы и выделены в с п е ц и а л ь н у ю г р у п п у к о м а н д , к о т о р у ю в ы тпроцессоры в в о д а - в ы в о д а е щ е д л я п е р в ы х п р о ц е с с о р о в , инпзации в в о д а - в ы в о д а п р о г р а м м и с т п и с а л к а н а л ь н у ю I ввода-вывода. К а н а л ь н а я п р о г р а м м а — э т о с л о ж н а я а , которая з а в и с е л а о т к о н к р е т н ы х у с т р о й с т в . И з Е устройства в в о д а - в ы в о д а п р и в о д и л о к н е о б х о д и м о с т и канальной п р о г р а м м ы , т а к , е с л и в м е с т о п р и н т е р а и с лось другое в н е ш н е е у с т р о й с т в о д л я з а п и с и р е з у л ь т а т о в , водимо было и з м е н и т ь к а н а л ь н у ю п р о г р а м м у . Д л я у п р о юграммирования в в о д а - в ы в о д а д л я к о н е ч н о г о п о л ь з о юдавались д р а й в е р ы — п р о г р а м м ы , у ч и т ы в а ю щ и е к о н и специфику у с т р о й с т в .
9.2.2. Драйверы для D O S 1лясамих устройств д р а й в е р ы в ы п у с к а ю т с я п р о и з в о д и т е л я ойств (драйвер д л я к о н с о л и — C O N , п р и н т е р а — L P T , ...). а драйверов о с у щ е с т в л я е т с я в о в р е м я з а г р у з к и О С . Т а к к а к try загрузки д р а й в е р а б о л ь ш и н с т в о с и с т е м н ы х п р о г р а м м пружены, п р о г р а м м ы - д р а й в е р ы н е м о г у т п е р е м е щ а т ь с я ига и применять ф у н к ц и и в в о д а - в ы в о д а О С , а и с п о л ь з у ю т •внкции BIOS. Т а к к а к п е р е к л ю ч е н и е в з а щ и щ е н н ы й р е шолняет ОС, д р а й в е р ы и с п о л ь з у ю т т о л ь к о р е а л ь н ы й р е ж и м L были быть з а п и с а н ы в к о р н е з а г р у з о ч н о г о д и с к а . И м е н а юв должны у к а з ы в а т ь с я в ф а й л е c o n f i g . s y s . Э т о н а к л а - ограничения на с т р у к т у р у д р а й в е р а — н е п е р е м е щ а е м ы й , язык написания д р а й в е р а — А с с е м б л е р . В н а ч а л е ф а й irt-овке) задается а д р е с н а ч а л а ф у н к ц и и и н и ц и а л и з а ц и и , 361
к о т о р а я п р и необходимости в ы д е л я е т п а м я т ь и ив ДЛЯW-. ее. Ф а к т и ч е с к и д р а й в е р и м е е т с т р у к т у р у : Реализация функций драйвера. Таблица функций. Функция инициализации. Ф у н к ц и я и н и ц и а л и з а ц и и з а п и с ы в а е т с я в конце npaiiepi I а в ы п о л н я е т с я п е р в о й с р а з у п о с л е е г о з а г р у з к и . Так кыг Щ ф у н к ц и я в ы п о л н я е т с я т о л ь к о о д и н р а з . посче ее выполнена» /а» мер д р а й в е р а у м е н ь ш а е т с я н а р а а м е р ф у н к ц и и инициал н и м и очередной д р а й в е р з а г р у ж а е т с я т а к и м образом, что nepe«ri*e | функцию инициализации. Т а б л и ц а ф у н к ц и й с о д е р ж и т с т р о к и , количество ROV о п р е д е л я е т с я ч и с л о м ф у н к ц и й . К а ж д а я строка содержит и • соответствующей ф у н к ц и и . Н о м е р с т р о к и таблицы для фу| о п р е д е л я е т с я номером этой ф у н к ц и и . Номера функций ставец н ы е д л я в с е х д р а й в е р о в . К р о м е ф у н к ц и и лнишшлиз, I в к л ю ч а л и в с е б я ф у н к ц и и ввода, в ы в о д а н т.д. Всего функ в с ч и т ы в а е т до 2 0 . Ф у н к ц и и в ы з ы в а ю т с я по номеру, а не во и<* • А н а л о г и ч н у ю с т р у к т у р у и м е ю т д р а й в е р ы LINLX для petu ного р е ж и м а . 9.2.3. Д р а й в е р ы для W I N D O W S 9 5 - 9 8 (VXD драймрн| Д р а й в е р ы м о г у т с о д е р ж а т ь ф у н к ц и и д л я работы в реяяаЯ и з а щ и щ е н н о м р е ж и м а х , в т о м ч и с л е ф у н к ц и и инициялиъг—» С т р у к т у р а д р а й в е р а ф и к с и р о в а н н а я . Есть специальный ша! ф у н к ц и й , к о т о р ы е д о л ж н ы в х о д и т ь в д р а й в е р . По яви ги с д р а й в е р а м и п р е д ы д у щ е г о т и п а о б р а щ е н и е к функциям m « л о ж е н и я и ОС о с у щ е с т в л я е т с я по н о м е р а м функций. Язык вр граммировання — Ассемблер, формат специальный. 9.2.4. Д р а й в е р ы для W I N D O W S NT (2000) и выше И з м е н е н и я в т р е б о в а н и я х к д р а й в е р у определяются в я н и я м и к ОС: м н о г о п л а т ф о р м е н н о с т ь и многопроцессоряог* П л а т ф о р м е н н о з а в и с и м ы е д р а й в е р ы с о с т а в л я ю т сисщ. # у р о в е н ь ( H A L ) у р о в е н ь . Д р а й в е р ы д л я этого уровня со—л » р а з р а б о т ч и к а м и а п п а р а т у р ы . Эти д р а й в е р ы должны р я т ь с т а н д а р т н ы м т р е б о в а н и я м к д р а й в е р а м , поэтому добяие» н о в ы х у с т р о й с т в , н а п р и м е р U S B . не д о л ж н о ничего излей»-, в д р а й в е р а х в е р х н е г о у р о в н я , к о т о р ы е используются прилшип i ем для чтения-записи информации. 362
9.3. Требования и особенности драйверов для WINDOWS 2 0 0 0 и выше 9.3.1.Совместимость с разными п л а т ф о р м а м и на у р о в н е исходных кодов Для реализации д р а й в е р а и с п о л ь з у е т с я я з ы к С и . Е с л и н е о б :ореализовать п р о ц е с с о р н о - з а в и с и м у ю о п е р а ц и ю , и с п о л ь з у мблерные в с т а в к и . О н и в с е р е а л и з о в а н ы т а к и м о б р а з о м , 1наэтапе компиляции м о ж н о б ы л о в ы б р а т ь т р е б у е м у ю п л а т iy. Так, в заголовочном ф а й л е N T D D K . H ч а с т о в с т р е ч а е т с я »«алогичный п р и в е д е н н о м у н и ж е : |
Mfined(_M_ALPHA) •ndif// defined(_M_ ALPHA) BetaJ(_M_/X86j lrntiimfined(_MJX86) «ifde/in ed(_M_IA64) ЫИ //deHned(M_IA64)
имерфункции для процессоров т и п а 1-32 soеэше целого числа со знаком в 64-битное число. inline LARGEJNTEGER NT АР! RtlConvertLongToLargelnteger ( >Signedlnteger) jsm( mov eax, Signedlnteger
'[ри компиляции д о с т а т о ч н о з а д а т ь т р е б у е м у ю д и р е к т и в у 2 это директива _М 1 X 8 6 ) . 0,2. Настраиваемость а п п а р а т н о г о и п р о г р а м м н о г о обеспечения ювеньНАЬ для к а ж д о й п л а т ф о р м ы р е а л и з о в а н с п о м о щ ь ю «установке ОС о п р е д е л я е т с я п л а т ф о р м а , и т р е б у е м а я :_навливается. Она э к с п о р т и р у е т ф у н к ц и и с и н т е р ф е й с о м , 363
к о т о р ы й н е з а в и с и т о т п л а т ф о р м ы . Э т о з н а ч и т , ч т о вызов фу1« п и й в д р а й в е р а х п р и о б р а щ е н и и к ф у н к ц и я м у р о в н я HAL » сит от платформы. Добавление н о в ы х устройств также ней»- т требуемого интерфейса. 9.3.3. В ы г р у ж а е м о с т ь и п р е р ы а е м о с т ь драйвере» П р и в ы п о л н е н и и п р и л о ж е н и й п о л ь з о в а т е л я потока* * • • п р и л о ж е п и я в ы д е л я ю т с я к в а н т ы в р е м е н и процессора (пропоров). П о а н а л о г и и д р а й в е р а м т а к ж е в ы д е л я ю т с я кванты i f " > « i Е с л и д р а й в е р ы не я в л я ю т с я д р а й в е р а м и ядра и не шдояцм* • в о п е р а т и в н о й п н м я т и . о н и м о г у т б ы т ь в ы г р у ж е н ы , как > п р и л о ж е н и е - Д л я д р а й в е р а о п р е д е л я е т с я п р и о р и т е т . Вьий г о б х о д и м о в ы п о л н и т ь п о т о к д р п й в е р а с б о л е е в ы с о к а н npi л » т е т о м . к в а н т в р е м е н и д л я д р а й в е р а с б о л е е н и з к и м приоритет* п р е р ы в а е т с я , з а п у с к а е т с я б о л е е п р и о р и т е т н ы й драйвер Ч о б е с п е ч и т ь в в и б о л ь ш и й п р и о р и т е т д р а й в е р а м устройств, в и nj# с в а и з а е т с я н а и в ы с ш и й у р о в е н ь п р и о р и т е т а DIRQL (Device I K Level). По у м о л ч а н и ю д р а й в е р а м , с в я з а н н ы м с устроители н а п р и м е р , д р а й в е р у ф а й л о в о й с и с т е м ы , присваивается д о к » п р и о р и т е т а PASSIVE LEVEL IRQL- Д р а й в е р а м , не с в я з и * * с в н е ш н и м и у с т р о й с т в а м и , п р и с в а и в а е т с я с а м ы й низин i Ц д р а й в е р о в у р о в е н ь п р и в и л е г и и D1SPA TCH_LEVEL Коикр*та4 з н а ч е н и й у р о в н е й п р и в и л е г и и , с о о т в е т с т в у ю щ и х данный с т а н т а м , О С н е п р и в о д и т , т а к к а к м е х а н и з м иаменения у ? " » * ' п р и в и л е г и й м о ж е т б ы т ь и з м е н е н в з а в и с и м о с т и от версии. К— • о б ы ч н о е п р и л о ж е н и е , д р а й в е р м о ж е т и м е т ь несколько п г * * » н о м н о г о п о т о ч н о с т ь д л я у в е л и ч е н и я п р о и з в о д и т е : 1ЬН0СТВЛ^> ров используется редко. 9.3.4. П о д д е р ж к а м н о г о п р о ц е с с о р н о с т и ОС W I N D O W S 98 о д н о п р о ц е с с о р н а я ОС, т.е. п с г п л » « » в и е н е с к о л ь к и х п р о ц е с с о р о в в м е с т о о д н о г о не увеличивает щ/ш и з в о д и т е л ь н о с т ь с и с т е м ы . W I N D O W S 2 0 0 0 поддерживает т п о л ь з о в а н и е н е с к о л ь к и х п р о ц е с с о р о в о д н о г о т и п а . Как а р а ш * п р о ц е с с о р з а к р е п л я е т с я з а п о т о к о м . И с п о л ь з о в а н и е вески ь м в п р о ц е с с о р о в п р и в о д и т к н е о б х о д и м о с т и р е ш е н и и проблемы сих р о н и з а ц и и д о с т у п а к о д н о м у р е с у р с у . П р и м е р : два п о т о м , шл • р ы е и с п о л ь з у ю т р а з н ы е п р о ц е с с о р ы , о б р а щ а ю т с я к клавиатуре Ч т о б ы р е ш и т ь э т у п р о б л е м у д л я п о л ь з о в а т е л ь с к о г о приложив»
ауются к р и т и ч е с к и е с е к ц и и , д л я д р а й в е р о в п р и м е н я ю т с я rlock, которые з а щ и щ а ю т р а з д е л я е м ы е д а н н ы е и р е г и с т р ы д о в р е м е н н о г о доступа одной и л и н е с к о л ь к и х ф у н к ц и й , в ы вяемых в симметричной с и с т е м е . Ч е м S p i n l o c k о т л и ч а е т с я от леской секции? Е с л и и с п о л ь з у е т с я к р и т и ч е с к а я с е к ц и я и шкый момент в р е м е н и п о т о к не м о ж е т в ы п о л н я т ь с я в с в я з и ; что ресурс занят д р у г и м п о т о к о м , п о т о к б л о к и р у е т с я до т е х I, пока ресурс не о с в о б о д и т с я . Б л о к и р о в а н и е т р е б у е т в р е м е н и «хода в режим я д р а д л я о с у щ е с т в л е н и я б л о к и р о в а н и я и вкирования. Ч а с т о это в р е м я б о л ь ш е , ч е м т р е б у е т с я ж д а т ь юждения критического р е с у р с а . Spinlock и с п о л ь з у ю т с я т о л ь инсгопроцессорными с и с т е м а м и , е с л и р а з н ы е п о т о к и в ы п о л |тся на разных п р о ц е с с о р а х . В з т о м с л у ч а е о д и н п о т о к м о ж е т . ать освобождения р е с у р с а б е з б л о к и р о в а н и я , в ы п о л н я я к о д : t e ( Р е с у р с занят). И м е н н о т а к о й р е ж и м и с п о л ь з о в а н и я п р е д п о г Spinlock. Е щ е р а з н а п о м и н а е м , ч т о и с п о л ь з о в а н и е э т о г о ма в однопроцессорной с и с т е м е н е э ф ф е к т и в н о ! Ядро обеспечивает д в а с п о с о б а у п р а в л е н и я Spinlock: -одна и только одна ф у н к ц и я м о ж е т п о л у ч и т ь д о с т у п к Spin1 в данный момент в р е м е н и . Д р у г а я ф у н к ц и я д о л ж н а п р и о б в Spinlock, прежде ч е м п о л у ч и т ь д о с т у п к д а н н ы м , но п р и о б не невозможно до о с в о б о ж д е н и я е г о — а н а л о г к р и т и ч е с к о й ^дашилимьютекса; -подобно векторам п р е р ы в а н и й , я д р о п р и с в а и в а е т к а ж д о | ~м1сск в системе у р о в е н ь IRQL. Ф у н к ц и я я д р а м о ж е т п р и о б 1 текущий Spinlock, т о л ь к о к о г д а ф у н к ц и я в ы п о л н я е т с я н а ^привилегии, п р и с в о е н н о м IRQL. Большинство д р а й в е р о в н и з к о г о у р о в н я н е в ы д е л я ю т о т шх потоков для у в е л и ч е н и я п р о и з в о д и т е л ь н о с т и . Ф у н к ц и и ! критичные п о в р е м е н и , д л я с и н х р о н и з а ц и и м о г у т и с кать объекты с и н х р о н и з а ц и и : K E V E N T , K M U T E X . П е р в а я чвимени типа означает, ч т о д а н н ы й т и п я в л я е т с я т и п о м д л я :овядра. 9.3.5. Максимальная модульность и независимость от изменений в д р а й в е р а х н и з ш е г о уровня счет чего можно с д е л а т ь п р о г р а м м у н а и б о л е е н е з а в и с и | [изменений? За счет и с п о л ь з о в а н и я о б ъ е к т о в . По а н а л о г и и •во рассматривается к а к о б ъ е к т . Д л я р а б о т ы с н и м О С э к с ярует функции, которые о б е с п е ч и в а ю т в ы п о л н е н и е н а и б о л е е 365
о б щ и х о п е р а ц и й и с в я з ь д р а й в е р о в м е ж д у собой. Все экспог™-—i р у е м ы е ф у н к ц и и и м е ю т и м е н а о д и н а к о в о й с т р у к т у р ы да» » • м о д у л е й О С и д о л ж н ы и м е т ь т а к у ю ж е с т р у к т у р у Д1я разр ваемых драйверов. Структура и м е н и : П р е ф и к с О п е р а ц и я ОбъектП р е ф и к с — о п р е д е л я е т с я м о д у л е м , к о т о р ы й экспортгчя эту ф у н к ц и ю . О п е р а ц и я — о п р е д е л я е т , ч т о д е л а е т д а н н а я функция. О б ъ е к т — з а д а е т и м я о б ъ е к т а , н а д к о т о р ы м выполвв»^ операция. П р и м е р ы о т д е л ь н ы х к о м п о н е н т о й и и м е н ф у н к ц и й арам* вы в табл. 9.1. Таблиц. Имена э к с п о р т и р у е м ы х функции Модуль ОС
Префикс
Операция
Объект
|
|
Имя ф у н т а ^
I/0-Manftger
10
Create
Device
loCreate DevKt
Kernel
Rtl
Zero
Memory
RtiZemfam*,
Hel
Hal
Translate
BusAddress
НвГГпт Address
Пример функции: loCreateDevice — ф у н к ц и ю э к с п о р т и р у е т I O-Maiuger- Выз ы в а е т с я э т а ф у н к ц и я д л я с о з д а н и я о б ъ е к т а устройства дли вывода, объект будет в ы п о л н я т ь запросы I/O. П о а н а л о г и и с О О П . д р а й в е р ы с а м о г о н и ж н е г о уровня» веры ф и з и ч е с к и х устройств) не и с п о л ь з у ю т функций ,f «ь д р а й в е р о в , т . е . я в л я ю т с я а н а л о г о м б а з и с н ы х ктоссов. Драйвер- I промежуточного и л и верхнего уровней рассматриваются М * | Ц е к т ы производные, они могут использовать функции faiHWU к л а с с о в ( д р а й в е р о в б о л е е н и з к о г о у р о в н я ) . К о м п о н е н т ы est* Л®* т а к ж е определяют объекты. К а ж д ы й компонент экс» ф у н к ц и и д л я м а н и п у л и р о в а н и я э к з е м п л я р а м и этих об-ъс» К о м п о н е н т ы не п о з в о л я ю т н а п р я м у ю использозать элемет 1 Щ г о г о о б ъ е к т а . К а ж д ы й к о м п о н е н т д о л ж е н в ы з в а т ь саециял|*«1 ф у н к ц и ю д л я д о с т у п а к э л е м е н т а м д р у г о г о о б ъ е к т а , если прн ф создании определена т а к а я возможность. Р а с с м о т р и м т и п ы о б ъ е к т о в и и х и е р а р х и ю д л я реа.тамдо п о л ь з о в а т е л ь с к о г о з а п р о с а I / O . С н а ч а л а рассматривается d h r . я д р а ОС « Ф а й л » . Этот о б ъ е к т п р е о б р а з у е т с я в объект драйвер*ФС
соответствует л о г и ч е с к о м у у с т р о й с т в у . Д л я п р о м е ж у [райвера объект п р е о б р а з у е т с я в виртуальное устройзатем, на самом н и з к о м у р о в н е , в о б ъ е к т « У с т р о й с т в о » , образом, I / 0 - M a n a g e r о п р е д е л я е т о б ъ е к т ы : ф а й л , у с т р о й | датг а е с к о е и виртуальное, о б ъ е к т д р а й в е р а у с т р о й с т в а . Ш. Использование стандартных п а к е т о в з а п р о с о в Зшросы на выполнение ф у н к ц и й д р а й в е р п о л у ч а е т от О С . Ъ ввести, WINDOWS р а б о т а е т н а п р и н ц и п е о б р а б о т к и с о которые О С п о с ы л а е т о к н а м . С о о б щ е н и я и м е ю т ф и к с и гую структуру, в к о т о р о й о п р е д е л е н о , ч т о н а д о с д е л а т ь ( к о д ли), параметры, к о т о р ы е п е р е д а ю т с я о к н у . П о а н а л о г и и , • формирует п а к е т с т а н д а р т н о г о в и д а , к о т о р ы й п е р е юйверу и между д р а й в е р а м и ( I / O request packet — IRP). рые разработчики О С W I N D O W S н а з ы в а ю т с о о б щ е н и я ной системой W I N D O W S , a I R P — к р о в е н о с н о й с и с т е м о й Г.ивной задачей I / 0 - M a n a g e r я в л я е т с я п р и е м з а п р о с о в I / O ко поступающих от п р и л о ж е н и й п о л ь з о в а т е л я ) с ц е л ь ю с о з впакета и передачи его с о о т в е т с т в у ю щ и м д р а й в е р а м , ч т о б ы (з лостью выполнить и в о з в р а т и т ь р е з у л ь т а т в ы п о л н е н и я 1ыждой операции I / O . К о м п о н е н т ы О С : I / O - M a n a g e r , P l u g ••Manager, Power M a n a g e r , н а з н а ч е н и е к о т о р ы х о ч е в и д н о * названия, используют п а к е т ы I R P д л я с в я з и с д р а й в е р а м и к , что н е к о т о р ы е п а к е т ы м о г у т б ы т ь о т п р а в л е н ы бо»ем одному драйверу. К п р и м е р у , з а п р о с на о т к р ы т и е ф а й л а «сначала н а д р а й в е р Ф С , з а т е м н а п р о м е ж у т о ч н ы й д р а й I атем на драйвер д и с к а , в о з м о ж н о , на P N P - ш и н н ы й д р а й в е р . Наждый пакет имеет ф и к с и р о в а н н у ю ч а с т ь и ч а с т ь , к о т о р а я втот драйвера. Фиксированная ч а с т ь ( з а г о л о в о к ) . I / 0 - M a n a g e r п о м е щ а е т «ацию об оригинальном з а п р о с е , т а к у ю к а к и д е н т и ф и к а т о р , затребовавшего о п е р а ц и ю , п а р а м е т р ы , т а к и е к а к а д р е с а устройства, на к о т о р о м ф а й л о т к р ы в а е т с я , и т . д . Ф и к с и и я часть также с о д е р ж и т п о л е д л я с о с т о я н и я о п е р а ц и и I / O |f)-tutus block), сюда д р а й в е р з а п и ш е т к о д р е з у л ь т а т а в ы п о л н е рвроса. [драйверов в ы с о к о г о у р о в н я и н ф о р м а ц и я , з а в и с и м а я гдшера для I / O - M a n a g e r , P l u g a n d P l a y M a n a g e r и л и P o w e r 367
M a n a g e r , с о д е р ж и т к о д т р е б у е м о й ф у н к ц и и и дополните . г и н ф о р м а ц и ю . С ю д а же з а п и с ы в а е т с я а д р е с д р а й в е р а более ЕМК> г о у р о в н я . П а к е т ф а к т и ч е с к и с о д е р ж и т и н ф о р м а ц и ю , достуиуя в с е м ф у н к ц и я м д р а й в е р а ( т а к ж е к а к д а н н ы е д л я класса), драЬ(| б о л е е в ы с о к о г о у р о в н я ф о р м и р у е т п о л я п а к е т а , которые « о й » димо передать дрвйверу следующего уровня. Р а с с м о т р и м п р и м е р и с п о л ь з о в а н и я д р а й в е р о в для вые н е н и я о п е р а ц и й C r e a t e F i l e и ReadFile. По о п е р а ц и и Crea(W-« I / O - M a n a g e r ф о р м и р у е т з а п р о с , в к о т о р о м определяет vcrpofr-т» и п у т ь д о с т у п а к ф а й л у , п а р а м е т р ы , к о т о р ы е задаются юи — м е н т ы ф у н к ц и и . Д р а й в е р в и р т у а л ь н о г о устройства ( С ) г ц я о б ъ е к т я д р а с и н ф о р м а ц и е й о ф а й л е и ф о р м и р у е т статус н о с т и з а в е р ш е н и я о п е р а ц и и . Э т о з н а ч е н и е д р а й е е р возврвш в к а ч е с т в е к о д а в о з в р а т а ф у н к ц и я м CreateFile и ReadFile. Г< тл п о л н а я а н а л о г и я в ы з о в а к о н с т р у к т о р а о б ъ е к т а , который зав»*» | е т все п о л я д а н н ы х д л я ф а й л я . Т а к к а к д р а й в е р работает в а " » в о м у р о в н е п р и в и л е г и и и д о л ж е н с о з д а т ь о б ъ е к т в области дар* н е о б х о д и м о п е р е п и с а т ь п а р а м е т р ы и з ф у н к ц и и CreatePil I я д р а . В з а п р о с е в п е р е м е н н о й ч а с т и з а д а е т с я адрес стека, « г » ^ н е о б х о д и м о б р а т ь п а р а м е т р ы (IrpStackLocalion). По ЭТОМУ за iуя 1 д р а й в е р ы более н и з к о г о у р о в н я , о п р а д е л я ю щ и е файловую п» м у (FSD), н д р а й в е р ы с а м о й ф а й л о в о й с и с т е м ы (NTFS) для яоет> к ф и з и ч е с к о м у у с т р о й с т в у н е в ы з ы в а ю т с я . П о операции R e a m ф о р м и р у е т с я запрос, к о т о р ы й с н а ч а л а обрабатывается Ы м п у с т р о й с т в а , н а п р и м е р , С:. В з а п р о с е п е р е д а е т с я пифорилщо . ф у н к ц и и . П о з н а ч е н и ю д е с к р и п т о р а д р а й в е р определяет д г ~ " н о с т ь д е с к р и п т о р а и в ы б и р а е т и н ф о р м а ц и ю из д е с к р и п т о р - -1 щ е е з н а ч е н и е с м е щ е н и я в ф а й л е , ф а й л о з а я система) и что кг, * ч и т а т ь . Д л я з а п и с и э т и х п а р а м е т р о в в с т е к очередного дра!вера | н е о б х о д и м о з н а т ь а д р е с э т о г о с т е к а . Д л я о п р е д е я е л и я адре •» • д л я д р а й в е р а о ч е р е д н о г о у р о в н я и с п о л ь з у е т с я ф у н к ц и я /oG{ S StackLocalion ( ч ь я э т о ф у н к ц и я ? ) . Д а л е е в ы з ы в а е т с я очор- » 3 д р а й в е р ц е п о ч к и ( у ж е д л я к о н к р е т н о й ф а й л о в о й спстемы|с п а » I щ ь ю ф у н к ц и и loCallDriver. С т р у к т у р а IRP о п р е д е л е н а в N T D D K . H 9.3-7. П о д д е р ж к а а с и н х р о н н о г о ввода-вывода Д л я у в е л и ч е н и я с к о р о с т и р а б о т ы и с п о л ь з у е т с я яснихрощшй в в о д - з ы в о д . К а ж д ы й д р а й в е р и м е е т с в о ю о ч е р е д ь . Для работы с о ч е р е д я м и и с п о л ь з у ю т с я с т а н д а р т н ы е ф у н к ц и и l/0-Macagr 368
М Е К Ц Н И loCallDriver о ч е р е д н о й з а п р о с на обработку запиr^wrca в очередь с л е д у ю щ е г о д р а й в е р а в ц е п о ч к е д р а й в е р о в . | | «вершении обработки з а п р о с а д р а й в е р о м н и ж н е г о у р о в н я [цвается функция loCompletion, в к о т о р о й , к а к п р а в и л о , e a rn „вается, что надо д е л а т ь по з а в е р ш е н и и о б р а б о т к и з а п р о с а •удным драйвером, н а п р и м е р , п е р е д а т ь к о д в о з в р а т а н а с л е д у [Мй уровень.
9.3.8. Особенности W D M - д р а й в е р о в Как следует из п р е д ы д у щ е г о м а т е р и а л а , д р а й в е р ы д л я W I N I 95 (98) по своей с т р у к т у р е о т л и ч а ю т с я от д р а й в е р о в д л я IHD0WS 2000 и в ы ш е . Д л я с о г л а с о в а н и я д р а й в е р о в д л я р а з 1ШХ версий WINDOWS р а з р а б о т а н а W I N D O W S D r i v e r M o d e l ИМ). Все WDM-драйверы с о о т в е т с т в у ю т у с т р о й с т в а м т и п а P N P •стрживают режим у п р а в л е н и я э н е р г о о б е с п е ч е н и е м . У с т р о й * называется устройством т и п а P N P , е с л и о н о п о з в о л я е т н а •вать значения номеров п р е р ы в а н и й и п о р т о в , с к о т о р ы м и отработать. Режим у п р а в л е н и я э н е р г о о б е с п е ч е н и е м н о з в о л я |г|вделить режимы с н а , т . е . у п р а в л я т ь э ф ф е к т и в н ы м и с п о л ь л'чем энергии. P N P - M a n a g e r — и с п о л ь з у е т с я д л я у п р а в л е н и я 'ЦР-чтройствами. P o w e r M a n a g e r и с п о л ь з у е т с я д л я у п р а в л е н и я вдгообеспечением. WDM-драйверы я в л я ю т с я с о в м е с т и м ы м и н а у р о в н е и с _jix кодов (но не в д в о и ч н о м в и д е ) с с и с т е м а м и M i c r o s o f t W I N № 98 и WINDOWS 2 0 0 0 ОС. Д л я о б е с п е ч е н и я и с п о л ь з о в а н и я а модели предусмотрена в о з м о ж н о с т ь с о г л а с о в а н и я э т и х ов с драйверами н и з к о г о у р о в н я (vxd и s y s ) . По структуре и ф у н к ц и я м W D M - д р а й в е р ы и д р а й в е р ы я д р а чны, поэтому в д а л ь н е й ш е м о н и не р а з д е л я ю т с я .
9.4. Использование установленных драйверов в пользовательских приложениях Ш. Определение и н ф о р м а ц и и об установленных драйверах Выше было сказано, ч т о I / O - M a n a g e r ф о р м и р у е т с т а н д а р т н ы й к драйверу и обеспечивает п е р е д а ч у э т о г о з а п р о с а по в с е й цедрайверов. Для о б е с п е ч е н и я д а н н о й ф у н к ц и и I / O - M a n a g e r 369
д о л ж е н в л а д е т ь и н ф о р м а ц и е й о б у с т а н о в л е н н ы х драйвера! * т п о д ч и н е н н о с т и . В с я э т а и н ф о р м а ц и я н а х о д и т с я в разделе реестр» HKEY_LOCALMACHINE\System\CurwritControlSetlServiCBS Д л я к а ж д о г о д р а й в е р а з а д а е т с я и н ф о р м а ц и я . Обяз ---и» м и я в л я ю т с я с л е д у ю щ и е п а р а м е т р ы : ImagePath. Start. Егти\'-.-?п Туре. П о л н ы й п у т ь к э т о м у д р а й в е р у . И м я э т о г о параметре Path. П р и м е р д л я д р а й в е р а д и с к е т ы ImagePath = Sysle • ; В VERS\flpdisk sys; В р е м я з а г р у з к и д р а й в е р а . П а р а м е т р определяет, кои ' г р у ж а е т с я д а н н ы й д р а й в е р и з а г р у ж а е т с я л и и ь вообще ibu э т о г о п а р а м е т р а Sf art- Э т о т п а р а м е т р п р и н и м а е т одно из пяти n>i ч е н и й . О — SERVICEBOOTSTART — з а г р у ж а е т с я яа 1-й з а г р у з к и я д р а О С . 1 — SERVICE_SYSTEM_START—загружу*, н а 2 - й с т а д и и з а г р у з к и я д р а О С . Э т о з н а ч е н и е использ)*жа . > п о л ь з о в а т е л ь с к и х д р а й в е р о в я д р а . 2 — SERVICE AUTO STAf' загрузка после загрузки модуля О С графического соль ч я | с к о г о и н т е р ф е й с а ( G U I ) . О б ы ч н о и с п о л ь з у е т с я д л я драйверов « У 3 — SERVtCE DEMAND START— д р а й в е р м о ж е т быть aai tram и л и и з п а н е л и у п р а в л е н и я , и л и к о м а н д о й NET START, н*шг щ ь ю S C M ( S e r v i c e C o n t r o l M a n a g e r ) A P I . 4 — SERVICEJHSAB £ драйвер выключен и не может быть загружен. С е р ь е з н о с т ь о ш и б к и . И м я э т о г о п а р а м е т р а ErrorCoi М о ж е т п р и н и м а т ь о д н о и з 4 - х з н а ч е н и й . О — SERVICEERT^ IGNORE. Э т о з н а ч е н и я с о о т в е т с т в у е т с а м о й н е з н а ч и т е л ь н а м | ке ( э т о о б ы ч н о п р е д у п р е ж д е н и е ) . И н ф о р м а ц и я заносится а « . н а л . но на э к р а н не в ы в о д и т с я . 1 SERVICE_ ERR0R_NQ4li% П о л ь з о в а т е л ю в ы в о д и т с я д и а л о г о в о е о к н о с инфориацо ш и б к е . 2 — SERVICE ERROR_SEVERE. В о з н и к л а серье«« о ш и б к е п р и з а г р у з к е д р а й в е р а . В ы п о л н я е т с я попытка пц,-*> грузки. 3 SERVICE_ ERROR CRITICAL. К р и т и ч е с к а я ошяЬ. к о т о р а я требует п е р е з а г р у з к и ОС. Е с л и д р а й в е р м о ж е т б ы т ь з а г р у ж е н т о л ь к о после задав*-* д р а й в е р а ( и л и г р у п п ы ) , д л я н е г о з а д а е т с я п а р а м е т р DependOoS* vice ( и л и DependOnGroup). Т и п д р а й в е р а . И м я п а р а м е т р а Т у р е . Туре 1 д л я дрл я д р а , 2 — д л я д р а й в е р а Ф С . о с т а л ь н ы е т и п ы анрезервироыи • | за службами. Д л я п р о с м о т р а э т и х д р а й в е р о в м о ж н о использовать р е ш т о р р е е с т р а RegEdit. Д л я п р о г р а м м н о г о о п р е д е л е н и я дрпйацй 370
имо использовать ф у н к ц и и д л я р а б о т ы с р е е с т р о м , к о т о иодят в WinApi. юграмма для определения с п и с к а д р а й в е р о в •elude %lude <stdic.h> ЧпсЫе <stringh> |p>e MAX_VALUE_NAME 80 m QueryKey(HKEY hKey)
CHAR achKey[MAXPA THJ; CHAR achClass[MAX_PATH] = ""; DWORD cchClassName = MAX_PATH;
DWORD cSubKeys; DWORD cbMaxSubKey;
DWORD сchMaxClass; DWORD cValues; DWORD cchMaxValue; DWORD cbMaxValueData; DWORD cbSecurityDescriptor; ГШШ
ftLastWriteTime;
DWORD i,j; DWORD retCode, retValue;
'№R achValue[MAXVALU E NAME]; WORD cchValue = MAX_VALUE_NAME; r
MRachBuff[80]; kgQuerylnfoKey(hKey,achC/ass, &cchClassName, NULL,&cSubKeys, kbUaxSubKey, &cchMaxClass, & cValues, &cchMaxValue, kbhlaxValueData, &cbSecurityDescriptor, &ftLastWriteTime); for[i=0, retCode = ERROR_SUCCESS; refCode == ERROR_SUCCESS; i++) { retCode = RegEnumKey(hKey, i, achKey, MAX_PATH); il (retCode == (DWORD)ERROR_SUCCESS) printf ("%s\n", achKey); 'icVataj tk Ц=0, retValue = ERROR_SUCCESS; j < cValues; j++) { ссШ.е = MAXVALUENAME; xhValue[0] = '10'; DWORD dwType; BYTE bcData[80]; reft/alue = RegEnumValue(hKey, j, achValue, &cchValue, NULL, Шуре, (PBYTE)achBuff, (DWORD*)bcData); if (retValue != (DWORD) ERROR_SUCCESS) continue; snitch (dwType) ( 371
case
case
}
REGDWORD: printf ("\t\t%s = %d\n", achValue, *(DWORD')achBuf' break; REGSZ: achBuff[*(DWORD*)bcData]=0; printf ("\t\t%s = %s\n". achValue, achBuff): break;
}
int main() { HKEY hkResult; LONG res1; LONG res = RegOpenKeyEx( HKEY_LOCAL_MACHINE, SYSTEM WCurrentControlSetUServicti 0, KEYJREAD, &hkResult ); if (res != ERROR_SUCCESS) { printf ("Open Registry Error\n"), return 1;
} char buffer[256]; char path[256] = "SYSTEMUCurrentControlSetUServicestt"DWORD dwLen = strlen (path) DWORD dwSize; HKEY hkSubKey; for (DWORD dwlndex = 0;; dwlndex++) { dwSize = sizeof (buffer); res = RegEnumKeyEx(hkResult. dwlndex. buffer, &dwSize, 0, 0, 0, 0); printf C%s\n' buffer); if (buffer[0]=='f) continue; strcpy (path + dwLen, buffer); res1 = RegOpenKeyEx( HKEY_LOCAL_MACHINE, path, 0, KEY_READ, &hkSubKey У. QueryKey(hkSubKey); res1 = RegCloseKey (hkSubKey); if (ERROR_NO_MORE_ITEMS == res) break;
} 372
Q ueryKey(hkResult); res = RegCloseKey(hkResult ); return 0; I Изучите функции д л я р а б о т ы с р е е с т р о м . Д л я ч т е н и я д а н н ы х «татра необходимо о т к р ы т ь р а з д е л , в к о т о р о м н а х о д я т с я э т и вые. Информация о д р а й в е р а х
—
в
HKEY_LOCAL_
разделе
^CHIHEWSYSTEMWCurrentControlSetWServices.
Имя
раздела
яи-
Игсярегистро-чувствительным. Д л я о т к р ы т и я р а з д е л а и с п о л ь • п функция RegOpenKeyEx,
формирующая
щения к разделу ( п а р а м е т р hkResult).
дескриптор
для
Ф у н к ц и я возвращает
В ошибки, который п р и у с п е ш н о м з а в е р ш е н и и ф у н к ц и и р а в е н №OR_SUCCESS. П о с л е з а в е р ш е н и я р а б о т ы с р а з д е л о м р е е с т р а ийодимо закрыть с о о т в е т с т в у ю щ и й р а з д е л ( ф у н к ц и я RegМеу). • Каждому установленному д р а й в е р у с о о т в е т с т в у е т п о д р а з д е л Юла драйверов. Д л я о п р е д е л е н и я э т и х п о д р а з д е л о в и с п о л ь з у ифункция RegEnumKeyEx. Д л я к а ж д о г о п о д р а з д е л а ( д р а й в е р а ) во определить и м е н а к л ю ч е й и их з н а ч е н и я . Д л я о п р е д е л е н и я •готической и н ф о р м а ц и и о к л ю ч а х и с п о л ь з у е т с я ф у н к ц и я KmrylnfcKey, которая в о з в р а щ а е т о б щ е е к о л и ч е с т в о к л ю ч е й , •шальный размер и д е н т и ф и к а т о р а к л ю ч е й и д р . И с п о л ь з у я Мвформацию, м о ж н о п о л у ч и т ь з н а ч е н и я и м е н и к л ю ч е й с п о »j® функции RegEnum Value. I
Разберитесь с о с о б е н н о с т я м и и с п о л ь з о в а н и я р а с с м о т р е н н ы х
§ший в примере, п р и в е д е н н о м в ы ш е . 9.4.2. Функция DeviceioControl. И с п о л ь з о в а н и е д р а й в е р а для работы с ж е с т к и м д и с к о м I Большинство ф у н к ц и й д р а й в е р а и с п о л ь з у е т с я д р у г и м и • • е р ш . Некоторые и з ф у н к ц и й м о г у т и с п о л ь з о в а т ь с я п о л ь игсльскими п р и л о ж е н и я м и н а п р я м у ю . В D O S д л я э т и х ц е л е й •изовались
так
называемые
ioctl
(imput/output
control)-функ-
ц которые позволяли в ы п о л н я т ь л ю б ы е ф у н к ц и и д р а й в е р а . •ItoBTEbix приложениях
используется
функция
DeviceioControl
а вызова функций д р а й в е р а . Д л я о б е с п е ч е н и я з а щ и т ы д р а й в е «ршюжение пользователя м о ж е т в ы з ы в а т ь т о л ь к о т е ф у н к а, которые «разрешает» в ы з ы в а т ь д р а й в е р , ч т о о п р е д е л я е т с я • его создании.
Ниже рассмотрена ф у н к ц и я
DeviceioControl и
^ерее использования с д р а й в е р о м ж е с т к о г о д и с к а . 373
Заголовок функции: BOOL
DeviceloControl( HANDLE hDevice, DWORD dwIoControlCode, LPVOID IplnBuffer, DWORD nlnBufferSize, LPVOID IpOutBuffer, DWORD nOutBufferSize, LPDWORD IpBytesReturned, LPOVERLAPPED IpOveriapped
); где: hDevice — д е с к р и п т о р д р а й в е р а , ф о р м и р у е т с я функцией CreateFile; dwIoControlCode — к о д ф у н к ц и и , к о т о р у ю надо выполнить; IplnBuffer — б у ф е р д л я и с х о д н ы х д а н н ы х . Равен 0, если исходные данные не требуются; nlnBufferSize — р а з м е р б у ф е р а д л я и с х о д н ы х данных в байтах; IpOutBuffer — б у ф е р д л я р е з у л ь т а т а ; nOutBufferSize — р а з м е р д л я р е з у л ь т и р у ю щ е г о буфера; IpBytesReturned — а д р е с п е р е м е н н о й , определяющей, ск< >ко байтов возвращено; IpOverlapped — а д р е с с т р у к т у р ы , к о т о р а я используется, если применяется асинхронный ввод-вывод. Пример использования функции. Д л я в с е х ж е с т к и х д и с к о в , у с т а н о в л е н н ы х в системе, определить их геометрические размеры. #include <windows.h> #include <winioctl.h> #include <stdio.h> #include <string.h> int main(){ char DriveNameO = "WW.WPHYSICALDRIVEO": int len = strlen (DriveName); for (int i = 0;;i++) { DriveName[len — 1]+=i; HANDLE hDrive = CreateFile (DriveName, GENERI C_ RE A D, FILE_SHA RE_ WRITE, 0, OPEN_EXISTING, 0, 0): if (hDrive == INVALID_HANDLE_VALUE) { 374
printf ("CreateFile
Error\n"); return
1;
} DISK_GECMETRY dg; DWORD dwBytesReturned; BOOL b = DeviceioControl ( hDrive, IOCTL_DISK_GET_DRIVE_GEOMETRY, 0, 0, &dg, sizeof (dg), &dwBy tesReturned, 0 ); if(!b) printf ("DeviceioControl: Error\n"); printf ('Cylinders = %Ld\n", dg.Cylinders.QuadPart); printf (BytesPerSector = %d\n", dg.BytesPerSector); printf ("SectorsPerTrack = %d\n", dg.SectorsPerTrack); printf ("TracksPerCylinder = %d\n", dg.TracksPerCylinder);
}
return 0;
I Как следует из п р и м е р а , ф у н к ц и и д р а й в е р а , д о с т у п к к о т о о возможен из ф у н к ц и и
DeviceioControl,
можно
вызывать
из
|№»8ательских п р и л о ж е н и й . Д р а й в е р с а м о п р е д е л я е т , к а к и е эфвкции будут д о с т у п н ы , ч ь и к о д ы б у д у т и з в е с т н ы п о л ь з о в а " Как определить т а к и е ф у н к ц и и в д р а й в е р е ? Э т о б у д е т р а с грено далее.
9.5. Разработка драйверов Программирование д р а й в е р о в — э т о в ы с ш и й п и л о т а ж в п р о г •вировании. В д а н н о м у ч е б н о м п о с о б и и н е в о з м о ж н о р а с с м о и все особенности с о з д а н и я д р а й в е р о в . Т а к , п р и с о з д а н и и Шшеров устройств н е о б х о д и м о х о р о ш о з н а т ь о с о б е н н о с т и •пения этими у с т р о й с т в а м и , т а к к а к э т о — п р о м е ж у т о ч н ы й ' между контроллером у с т р о й с т в а и п р и л о ж е н и я м и п о л ь з о в а ии.3десь будут рассмотрены н а ч а л ь н ы е с в е д е н и я , н е о б х о д и м ы е • оздания любого д р а й в е р а , и п р и м е р с о з д а н и я п р о с т е й ш е г о ; мера. После и з у ч е н и я д а н н о г о р а з д е л а р е к о м е н д у е м р а с ь примеры д р а й в е р о в , д л я к о т о р ы х п р и в е д е н ы и с х о д н ы е •изDevice Driver Kit. 9.5.1. Классификация д р а й в е р о в д л я W i n 3 2 I
Используется три у р о в н я д л я д р а й в е р о в : драйверы высокого уровня,
такие
как драйверы
файло-
йгкгем; FAT, NTFS, и C D F S ( F S D s ) . Э т и д р а й в е р ы з а в и с я т •
нестоящих драйверов. В то в р е м я к а к д р а й в е р ФС з а в и с и т 375
от одного или более промежуточных устройств, в конечном c i - ^ он зависит от драйверов п е р и ф е р и й н ы х устройств (и возхшп от драйвера P N P - ш и н ы ) . • Промежуточные драйверы (для виртуального даек* драйвер класса устройства. Промежуточные драйверы, в к о г ном счете, т о ж е зависят от драйверов нижнего уровня. • Драйверы нижнего уровня, т а к и е как драйверы шины l управляющие ш и н о й I / O , через которую к вычисчительнонсг ме подключается внешнее устройство. Низкоуровневые драйверы не з а в и с я т от д р у г и х драйверов, но управляются физнчмк»* устройством, т а к и м к а к ш и н а . Сетевые драйверы W I N D O W S 2 0 0 0 относятся к одв< базисных типов. Так, NT-server, или мвршрутизатор, OTHI к драйверам ФС; любой драйвер, который осуществляет пе]» i ' данных, относится к промежуточному драйверу; в драйвер с»» вой карты — драйвер н и ж н е г о уровня. Д л я сетевых драйвере есть специальный стандарт NDIS ( N e t w o r k Device Interfa«> fication), и драйверы этого типа удовлетворях>т этому ст« цЩ 9.5.2. Структура драйвера Д р а й в е р имеет расширение sys и является файлол форм* РЕ. Поэтому его можно просматривать с помощью Dumpbm Tilump, в том числе, просматривать его экспортируемые фуи ции. Например, д л я драйвера flpydisk-sys можно получвп eg формацию по коменде: dumpbm /ALL flpydisk.sys Как показывает исследование этого драйвера, он не 3i • - ; тирует ф у н к ц и и , т.е. его ф у н к ц и я м и не пользуются друп да! веры. Он сам импортирует ф у н к ц и и ядра и Hal. Как и любое другое приложение, драйвер содержит: П р | вую функцию с именем DriverEntry* и другие функции. Функцы драйвера описаны н и ж е . 9.5-3. Стартовая функция
DriverEntry
С т а р т о в а я ф у н к ц и я в ы з ы в а е т с я операционной система! сразу после загрузки драйвера. Эта ф у н к ц и я исполняет роль структора д л я объекта, она з а п о л н я е т поля объекта, вызыме i 1 Имя это» функции может Бить другим, но в этой случае его к.чйкоднмо авь компоновщику.
370
.копри его создании. Э т о ф у н к ц и я о б р а т н о г о в ы з о в а , е е в ы и етОС, а не п р и л о ж е н и е . I
Заголовок функции: NTSTATUS DriverEntry( INFDRIVER OBJECT DriverObject, IH PUNICODE_ STRING RegistryPath
I
j,
т IN, OUT — о б о з н а ч е н и е и с х о д н ы х п а р а м е т р о в и р е з у л ь т а т о в , •метственно. Эти о б о з н а ч е н и я о п р е д е л е н ы к а к : «define IN ((define OUT используются для н а г л я д н о с т и . DRIVER OBJECT— о б ъ е к т ; иять выделяет I / O - M a n a g e r .
«Устройство».
Под
сам
объект
UMCODE_STRING — с т р о к а , к о т о р а я о п р е д е л я е т и м я д р а й ((а в реестре. Память в ы д е л я е т с я I / 0 - M a n a g e r . Возвращаемое а п а ч е н и е — к о д о ш и б к и . Т и п э т о й о ш и б к и — 'STATUS. Формат о ш и б к и э т о г о т и п а т а к о й ж е , к а к д л я о ш и б к и , к у ю возвращают в с е ф у н к ц и и WinApi ( ф у н к ц и я GetLastError). Неуспешном з а в е р ш е н и и NTSTATUS STATUSSUCCESS. Функция в ы п о л н я е т с я с у р о в н е м п р и в и л е г и и IRQL_PAS:„E_LEVEL. Н а п о м и н а е м , ч т о п о с л е в ы п о л н е н и я и н и ц и а л и з а . модуль, в котором р е а л и з о в а н а ф у н к ц и я и н и ц и а л и з а ц и и , ^сывается, поэтому о б р а щ е н и е к ф у н к ц и и в н у т р и д р а й в е р а н е «пускается. Стартовая ф у н к ц и я д о л ж н а в ы п о л н и т ь с л е д у ю щ и е д е й ця. 1.Заполнить поля д л я о б ъ е к т а DRIVER OBJECT. О п и с а н и е tea (основные п о л я ) : lypedef struct _DRIVER_OBJ ЕСТ { CSHORT Туре; //Тип объекта CSHORT Size; // Размер структуры в байтах PDEVICEOBJECT DeviceObject;// Адрес объекта типа // «Устройство» ULONG Flags;//Флаги PVOID DriverStart;// Время загрузки (смотри ниже) ULONG DriverSize;// Размер драйвера PVOID DriverSection; //Адрес начала секции драйвера PDRIVER EXTENSION 0гЫегЕх1епзюп;//Дополнительная //информация о драйвере. Имя драйвера используется при И записи в журнал сообщения об о ш и б к е 377
UNICODESTRING DnverName;
//Используется, если драйверу необходимо работать И с registry. Это папка в реестре, куда записывается // информация.
PUNICODE STRING HardwareDatabase.
// Определение точек входа в основные функции драйвера PDRIVERJNITIALIZE Driverlnit PDRIVERSTARTIO DrlverStartlo. PDRIVER UNLOAD DriverUntoad: PDRIVER_ DISPATCH MajorFunction IRP_MJ MAXIMUM F(A CTION+1). } DRIVERJDBJECT:
2. ЗАПОЛНИТЬ м а с с и в ф у н к ц и й MajorFunction адресами ? и ц и й , к о т о р ы е в ы п о л н я е т д р а й в е р . С р е д и н и х есть СЛРГ - * Р» ф у н к ц и и : IRP MJ CREATE IRP_MJ_CLOSE, IRP^MJ SYSTEM CONTROL например: DnverOb/ect-> MaforFunction [IRP_MJ_CREATE] = MyDDi фМСпая DriverObject-> MajorFunction[IRP_MJ_PNP} = MyDDispatcbPNP DriverObject-> MajorFunction[[IRP_MJ_POWERI = MyDD p^tchFoiv IDispatch—быстрое выполнение) 3 . Если д р а й в е р у н е о б х о д и м о передавать параметры, т а ж е н стек, необходимо с о з д а т ь о б ъ е к т устройства. В атом с ? ••• ф у н к ц и я д л я с о з д а н и я о б ъ е к т а устройства определяется в т— расширения объекта драйвера, например: DrlverObject->DriverExfension->AddDevice MyDAddD> [ се 4 . В о з в р а т и т ь п р и з н а к б л а г о п о л у ч н о г о завершения: return STATUS_SUCCESS. П р и м е р с т а р т о в о й ф у н к ц и и п р и в е д е н н и ж е после следующе! функции. 9.5.4. Ф у н к ц и я AddDevice Ф у н к ц и я использует следующие параметры: и м я устройства. З а д а е т с я к а к к о н с т а н т а в видестрокиЬУ CODE, напримерLWDeviceWHMB. — и м я устройства, которое и с п о л ь з у е т с я к а к DOS-имя. вмел но э т о и м я з а д а е т с я п р и вызове CreateFile. З а д а е т с я как копе гаи» в виде с т р о к и UNICODE, н а п р и м е р LWDosDevicesWMup. Заголовок функции: NTSTATUS Имя [IN PDRIVER_OBJECT DnverObtea IN PDEVICE_OBJECT PhysicelDeviceObject).
Адрес объекта у с т р о й с т в а , к о т о р ы й с о з д а е т с я н и ж е в ф у н к В этой функции н е о б х о д и м о з а д а т ь п е р е м е н н ы е : Т DeviceObject; "вера);
PLOCALJDEVICEJNFO
UNICODE
STRING
Devicelnfo
DestinationString;
PDEVICE(зависит
NTSTATUS
Sta-
Вфункции н е о б х о д и м о в ы п о л н и т ь : 1. Определить и м я у с т р о й с т в а по
и м е н и ф а й л а (L"\\Device\\
И: RtllnitUnicodeString( PUNICODE_ STRING DestinationString, PCWSTR SourceString
): 2. Определить объект у с т р о й с т в а с п о м о щ ь ю ф у н к ц и и loCreate. Заголовок ф у н к ц и и : NTSTATUS loCreate Device ( IN PDRIVERCBJECT DriverObject, IN ULONG DeviceExtensionSize, //Размер, 0, если не надо IN PUNICODE STRING DeviceName OPTIONAL, IN DEVICE TYPE DeviceType, //FILE_DEVICE_ UNKNOWN, //если хотим видеть для любого загруженного пользователя. IN ULONG DeviceCharacteristics, //Только для ФС и дисков, //иначе О IN BOOLEAN Exclusive, //true, если доступ только одного //потока, для для PNP устройств — false OUT PDEVICE OBJECT *DeviceObject I; Пример вызова: Status = loCreateDevice(DriverObject, sizeof (LOCAL_DEVICE_INFO), DeviceName, DeviceType, 0, true, DeviceObject I if (Status != STATUS_ SUCCESS) return Status; Скопировать и м я Д О С - у с т р о й с т в а в с т р о к у UNICODE ( ф у н к uRtllnitUnicodeString). 3. Задать связь м е ж д у р а з н ы м и и м е н а м и ( ф у н к ц и я loCreatebolicLink(Имя Д О С - у с т р о й с т в а , Н о в о е И м я у с т р о й с т в а ) ) . Е с л и задании связи о ш и б к а (Status), Ьщанное устройство
(функция
то н е о б х о д и м о у н и ч т о ж и т ь loDeleteDevice
(Адрес
устрой-
гм)). Переписать и н ф о р м а ц и ю о д р а й в е р е , е с л и о н а е с т ь , и з п о л я |кдшрения для о б ъ е к т а д р а й в е р а . Э т а и н ф о р м а ц и я м о ж е т с о д е р иг: адрес объекта у с т р о й с т в а , с л е д у ю щ и й д р а й в е р в ц е п о ч к е , 379
н о м е р а и к о л и ч е с т в о п о р т о в , е с л и д р а й в е р д л я р а б о т ы с портами.
...Devicelnfo
=
DeviceObject->DeviceExtension.
З а д а т ь с в я з и м е ж д у т е к у щ и м и н и ж е с т о я щ и м устройствами (функция loAttachDeviceToDeviceStack). Заголовок функции:
PDEVICE_OBJECT loAttachDeviceToDeviceStack( IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice ); Пример:
Devicelnfo->NextLowDriver = loAttachDeviceToDeviceStack (Devic Object, PhysicalDeviceObjrct); If (Devicelnfo->NextLowDriver==0){ loDeleteSymbolicLink (& куда скопировано ДОС-устройств с loDeleteDevice (&объекта устройства); status = STATUS NO_SUCH_DEVICE; } Пример стартовой функции1:
NTSTATUS DriverEntry( IN PDRIVEROBJECT DriverObject, IN PUNICODE STRING RegistryPath
){ UNREFERENCED PARA ME TER (Regis try Path);// DnverObject->MajorFunction[IRP_MJ_CREATE] = GpdDispatc DriverObject->MajorFunction[IRP_MJ_CLOSE] = GpdDispatch; DriverObject->MajorFunction[IRP_MJ_ DE VI CE_ С ONTROL] = GpdDispatch; DriverObject->DriverUnload - GpdUnload; DriverObject->MajorFunction[IRP_MJ_PNP] = GpdDispatchPnp; DriverObject- >MajorFunction[IRP MANPOWER] = GpdDispatchPcwer DriverObject-> MajorFunction[IRP_ MJ SYSTEM_CONTROL] = Gpdt ispa tchSystem Control; DriverObject>DriverExtension->AddDevice = GpdAddDevice, return STATUS SUCCESS;
} В э т о й ф у н к ц и и с т р о к а с п у т е м д о с т у п а к р е е с т р у не сохраняе т с я , т а к к а к н е п р е д п о л а г а е т с я п о т о м з а п и с ы в а т ь и считывать доп о л н и т е л ь н ы е п а р а м е т р ы . Gpd — п р е ф и к с д л я д р а й в е р а , который называется
Gpd.
1 При задании стартовой функции предполагается, что префикс драйвера, д.и которого создается эта функция, MS J.
380
9.5.5. Реализация ф у н к ц и й о б р а б о т ч и к о в . Функция MKC>DispatchCreate Функция д о л ж н а : -определить ф л а г з а в е р ш е н и я ; -определить н е о б х о д и м о с т ь и з м е н е н и я у р о в н я п р и в и л е г и и •^завершения в ы п о л н е н и я ф у н к ц и и . Примеры р е а л и з а ц и и ф у н к ц и й : HTSJATUS MyDDispatchCreate (IN PDEVICE OBJECT DeviceObject, IN PIRP Irp){ IrpjlcStatus. Status = STATUSS_SUCCESS; l\lrp->loStatus.lnformation = 0; loCompleteRequest (Irp, IONOJNCREMENT); Return lrp->loStatus. Status; lrp->loStatus.Status
9.5.6. Функция < П р е ф и к с > С о т р 1 е Ь ' о п Я о и Н п е Функция вызывается по с о о б щ е н и ю , с в я з а н н о м у с з а в е р ш е • работы н и ж е с т о я щ е г о д р а й в е р а . Ф у н к ц и я д о л ж н а в ы п о л •следующие о п е р а ц и и : [
1. Инициализировать
поля
DRIVER
OBJECT.
Поля
этой
'ШШ задают т а б л и ц у о б р а б о т ч и к о в ф у н к ц и й д р а й в е р а , в т о м НЕ Startlo, Unload, ф у н к ц и и , к о т о р ы е м о ж н о в ы з ы в а т ь с п о м о •Dewce/oConfro/. 2 . Если устройство д о л ж н о п о д д е р ж и в а т ь P l u g a n d P l a y ЯЗР). должна быть в ы п о л н е н а ф у н к ц и я AddDevice. I
3.Параметр RegistryPath з а д а е т п у т ь к и м е н и д р а й в е р а в р е е Драйвер может и с п о л ь з о в а т ь р е е с т р д л я з а п и с и и н ф о р м а ц и и
Параметров. Если д р а й в е р у н е о б х о д и м о и с п о л ь з о в а т ь э т о т к а т а ш после выполнения ф у н к ц и и DriverEntry,
драйвер д о л ж е н за-
•юыюпию этой с т р о к и , а н е у к а з а т е л ь н а н е е , т . к . I / 0 - M a n a g e r рюдит буфер с RegistryPath п о с л е з а в е р ш е н и я DriverEntry. Драйверы ядра не о б я з а т е л ь н о о б р а б а т ы в а ю т з а п р о с ы в т о м • порядке, как они п о с т у п а ю т . I / 0 - M a n a g e r м о ж е т п е р е у п о р я д о *>запросы или м о ж е т р а з д е л и т ь з а п р о с , т р е б у ю щ и й о б р а б о т к и •лшого объема д а н н ы х на н е с к о л ь к о з а п р о с о в . В с л у ч а е и с п о л ь kaiil нескольких п р о ц е с с о р о в , м о ж е т п а р а л л е л ь н о в ы п о л н я т ь •осы I/O. Более того, д р а й в е р н е в ы п о л н я е т з а п р о с п о л н о с т ь ю , . для каждого пакета н е л ь з я с к а з а т ь , ч т о с л е д у ю щ и й з а п р о с VT выполнен только п о с л е п о л н о й о б р а б о т к и э т о г о п а к е т а , к а к * ныло для однозадачных о д н о п р о ц е с с о р н ы х ОС. П р и п е р е д а ч е 381
п а к е т а д р а й в е р у более н и з к о г о у р о в н я д р а й в е р ждет возврате сос т о я н и я в ы п о л н е н и я о п е р а ц и и ( п о л е статуса). Драйверы т*«« м о г у т з а п о м и н а т ь и н ф о р м а ц и ю о т е к у щ и х операциях I О • *> ц и а л ь н о й ч а с т и их о б ъ е к т а у с т р о й с т в а , н а з ы в а е м о м devir* р sionР а с с м о т р и м а л г о р и т м о б р а б о т к и з а п р о с а ввода-вывода п п р и м е р е д р а й в е р а ФС. I / 0 - m a n a g e r ф о р м и р у е т запрсн. и вызым-ч д р а й в е р ФС (FSD) с запросом. F S D р а с с м а т р и в а е т полеI/OSTACK LOCATION в п а к е т е д л я о п р е д е л е н и я , к а к у ю операцию надо IUполнить. F S D м о ж е т р а з б и т ь о д и н з а п р о с на несколько(воз«« «» д л я н е с к о л ь к и х у с т р о й с т в ) , и с п о л ь з у я ф у н к ц и ю (i'oaf/ocaJ*«* один и л и б о л е е р а з д л я ф о р м и р о в а н и я дополнительных пакт** Д л я д о п о л н и т е л ь н ы х п а к е т о в п о л я I/O STACK, сформировании» д л я н и з к о у р о в н е в ы х д р а й в е р о в , н у л е в ы е . FSD может использов а т ь и с х о д н ы й п а к е т вместо ф о р м и р о в а н и я новых пакетов. н а в л и в а я д л я низкоуровневого д р а й в е р а п о л е Ю STACK LOCAVW оригинального irp. Д л я к а ж д о г о п а к е т а FSD в ы з ы в а е т ф у н к ц и ю юдейюМр stacklocation д л я п о л у ч е н и я адреса с л е д у ю щ е г о драйвера. F S D в ы з ы в а е т ф у н к ц и ю iocalldriver д л я перехода ва очере,»^ драйвер. Н и з к о у р о в н е в ы й д р а й в е р о п р е д е л я е т требуемую фуакаш в I/O STACK LOCATION (обозначается кодом irp jnjjead. гф_<ц_ write). Обычно д р а й в е р в ы с ш е г о у р о в н я проверяет правнльв . и параметров д л я требуемой о п е р а ц и и , а д р а й в е р нижнего урови предполагает, что п а р а м е т р ы з а д а н ы верно. Если у драйвера вв>него у р о в н я д р а й в е р а высшего у р о в н я нет, то драйвер нижмо у р о в н я д о л ж е н с д е л а т ь э т у п р о в е р к у сам- Если все в иорц*.' д р а й в е р обычно в ы з ы в а е т ф у н к ц и ю I / O - M a n a g e r д л я соовщгим о т о м , что з а п р о с п р и н я т к и с п о л н е н и ю и следует ожидать его в ы п о л н е н и я , а т а к ж е п е р е д а е т его д р а й в е р у нижнего уровня я л в ы п о л н я е т этот запрос с а м . Н а п о м и н а е м , что переход между >;••» н я м н в ы п о л н я е т I / O - M a n a g e r . Он п р о в е р я е т , свободен драйвер, которому надо передать п а к е т , и л и нет- Если нет. то ставит пакет в очередь. В п р о т и в к о м с л у ч а е з а п у с к а е т с я ф у н к ц и я , которая вып о л н я е т о п е р а ц и ю I / O н а э т о м устройстве. Обработчик п р е р ы в а н и я д л я д р а й в е р а (interrupt service routine — txr) в ы п о л н я е т м и н и м а л ь н у ю работу, а именно: от ключа ет п р е р ы в а н и я {CLI) и с о х р а н я е т необходимую информацию ди в ы п о л н е н и я о п е р а ц и и . З а т е м обработчик прерызаиий выэьпая 382
гикцию iorequestdpc с п а к е т о м в о ч е р е д и д л я з а в е р ш е н и я в ы чюяеыой о п е р а ц и и с б о л е е н и з к и м у р о в н е м п р и о р и т е т а , ч е м у %ботчика п р е р ы в а н и й , и р а з р е ш а е т п р е р ы в а н и я . К о г д а э т а Гшпя драйвера п о л у ч а е т у п р а в л е н и е , о н а и с п о л ь з у е т д а н н ы е , мученные ф у н к ц и е й i o r e q u e s t d p c д л я з а в е р ш е н и я о п е р а ц и и ( О Эта функция в ы з ы в а е т ф у н к ц и ю д л я и з в л е ч е н и я п а к е т а и з ?ереди, передает п а к е т ф у н к ц и и , н а ч и н а ю щ е й о п е р а ц и ю I / O . f t функция з а т е м у с т а н а в л и в а е т к о д з а в е р ш е н и я в п о л е status -летайвозвращает е г о I / O - M a n a g e r . I/0-Majiager о б н у л я е т п о л е а д р е с а с т е к а д р а й в е р а н и ж н е г о ; вня в пакете и в ы з ы в а е т з а р е г и с т р и р о в а н н у ю ф у н к ц и ю з а ушения, о к о т о р о й г о в о р и л о с ь в ы ш е . Э т а ф у н к ц и я п р о в е р я е т с : завершения в п а к е т е д л я о п р е д е л е н и я , н у ж н о л и п о в т о р и т ь шрос или обновить в н у т р е н н е е с о с т о я н и е о з а п р о с е и о с в о б о д и т ь -мять, выделенную д л я п а к е т а .
ФС м о ж е т с о е д и н и т ь в ц е л о е
завершения д л я в с е х п а к е т о в , к о т о р ы е о н а п о с ы л а л а д р а й вам нижнего у р о в н я , т о г д а о н а у с т а н а в л и в а е т к о д з а в е р ш е н и я и .лсывает его в о р и г и н а л ь н ы й п а к е т . И м е н н о э т о т к о д в о з в р а щ а •ввфункцию, к о т о р а я д е л а л а з а п р о с I / O .
9.5.7. Функции для выполнения базисных о п е р а ц и й (irp_m/_xxx) Множество г л а в н ы х и п о д ф у н к ц и й с п е ц и ф и ч н ы д л я р а з л и ч „ л драйверов. Н о д р а й в е р ы н и ж н е г о у р о в н я и п р о м е ж у т о ч н ы е - "верывсегда и м е ю т т а к и е ф у н к ц и и : lrp_mj_create — о т к р ы в а е т ц е л е в о й о б ъ е к т , д е л а е т е г о д о с т у п ; л для операции I / O ; Irimjjead- - п е р е д а ч а д а н н ы х
от у с т р о й с т в а ;
lrp_mj_write — п е р е д а ч а д а н н ы х к у с т р о й с т в у ; lrp_wj_device_control — м н о ж е с т в о с е р в и с о в ,
которые можно
пользовать с п о м о щ ь ю ф у н к ц и и d e v i c e i o c o n t r o l ; lrp_mj_close — з а к р ы т и е о б ъ е к т а . \rpjnjjpnp — в ы п о л н я е т о п е р а ц и ю p l u g - a n d - p l a y д л я у с т р о й -А. Запросы
irp_mj_pnp
посылаются
PNP-MANAGER
через
0-Manager. lrp_mjjpower — в ы п о л н я е т о п е р а ц и ю у п р а в л е н и я я устройства.
Запрос
irp_mj_power п о с ы л а е т с я
POWER
энергией MANA-
ER через I / 0 - M a n a g e r . I/0-Manager о п р е д е л я е т т и п д р а й в е р а , и с п о л ь з у е м ы е о б ъ е к идлярегистрации, и о п р е д е л я е т т и п о б ъ е к т а д р а й в е р а и и с п о л ь с.тобъекты д р а й в е р а д л я р е г и с т р а ц и и .
383
Д л я н и з к о у р о в н е в о г о д р а й в е р а dispatch ф у н к ц и ю обыч^ в ы з ы в а е т ф у н к ц и я lostartpacket д л я п о с т а н о в к и в очередь нля п е р е д а ч и п а к е т а с п р а в и л ь н ы м и п а р а м е т р а м и функции slartx Ф у н к ц и я startio н а ч и н а е т о б р а б о т к у запроса на конкретном ' j ройстве. Д л я д р а й в е р о в в е р х н е г о у р о в н я т а к о й функции обьгаг нет. К о г д а д р а й в е р з а г р у ж е н , в ы з ы в а е т с я ф у н к ц и я dnveranby с у к а з а т е л е м на о б ъ е к т . Ф у н к ц и я о п р е д е л я е т одну или болы» т о ч е к входа dispatch, тик ч т о I / O - M a n a g e r м о ж е т связать пакеты с с о о т в е т с т в у ю щ и м и ф у н к ц и я м и dispatch. Ф у н к ц и я drivers у т а к ж е у с т а н а в л и в а е т т о ч к и в х о д а startio в unload в объекте дрл!вер а . и адрес ф у н к ц и и adddevice в п о л е dnverextension. D n v e r e n t r y и л и н е о б я з а т е л ь н а я ф у н к ц и я reinitialize т е м и могут ч и т а т ь - п и с а т ь и н ф о р м а ц и ю и з реестра. Подобно всем с и с т е м н ы м о б ъ е к т а м , о б ъ е к т драйвера являетс я з а к р ы т ы м : т о л ь к о с и с т е м н ы й к о м п о н е н т (здесь 1/О-МаптП «знает* его в н у т р е н н ю ю с т р у к т у р у и м о ж е т напрямую работать с н и м . П р и р а з р а б о т к е д р а й в е р о в необходимо использовать функц и и д л я работы с з т п м и о б ъ е к т а м и . К п р и м е р у , ядро экспорту — ф у н к ц и ю д л я в ы з о з а I / O - M a n a g e r д л я и н и ц и а л и з а ц и и н опредг л е н и я о б р а б о т ч и к а п р е р ы в а н и й д л я д р а й в е р а нижнего урова» ( ф у н к ц и я ddinterwplservice). Ч т о б ы д о с т и г н у т ь солпой совместамости, всегда н у ж н о и с п о л ь з о в а т ь ф у н к ц и и ядра. 9.5.8. Точки в х о д а стандартного объекта драйвера Д р а й в е р я д р а д о л ж е н о п р е д е л и т ь с л е д у ю щ и е точки нов* в объекте драйвера: — по к р а й н е й мере, о д н у d i s p a t c h - ф у н к ц и ю д л я выполнены P N P , power и о п е р а ц и й I / O ; — ф у н к ц и ю adddevice, в driverobject - > dnverextension - » ddevice; — ф у н к ц и ю startio. е с л и он у п р а в л я е т сам своей о»»гт-.« пакетов. Е с л и д р а й в е р м о ж е т з а г р у ж а т ь с я и выгружаться динамичес к и , то д о л ж е н и м е т ь ф у н к ц и ю д л я о с в о б о ж д е н и я своих pecvp > т а к и х к а к п а м я т ь , которую д р а й в е р в ы д е л и л . Д р а й в е р ы , к о т о р ы е м о г у т б ы т ь з а м е н е н ы без перрзагру(т с и с т е м ы , т а к и е к а к д р а й в е р ы к л а в и а т у р ы , ф у н к ц и я выгрузки, ве требуются. Л ю б о й д р а й в е р , к о т о р ы й п о д д е р ж и в а е т P N P , должен шить ф у н к ц и ю adddevice. Ф у н к ц и я adddevice создает один или боям
(VKTOB, соответствующих ф и з и ч е с к о м у , л о г и ч е с к о м у и л и в и р «иьному устройствам, д л я к о т о р ы х д р а й в е р в ы п о л н я е т з а п р о ЦО. Драйверы самого н и ж н е г о у р о в н я н е д о л ж н ы о б я з а т е л ь н о чь функции startio. В о т п о ч е м у , б о л ь ш и н с т в о т а к и х д р а й в е р о в «меют функции s t a r t i o и д о в е р я ю т у п р а в л я т ь о ч е р е д ь ю п а к е т о в O-Manager. Некоторые и з д р а й в е р о в э т о г о т и п а н е и м е ю т ф у н к Biistartio, даже е с л и с а м и у п р а в л я ю т о ч е р е д ь ю п а к е т о в . Г Драйверы верхнего у р о в н я м о г у т и м е т ь ф у н к ц и ю startio, но •обеспечения б о л ь ш е й п р о и з в о д и т е л ь н о с т и р е д к о е е и с п о л ь з у п . Вместо этого б о л ь ш и н с т в о д р а й в е р о в Ф С д л я W I N D O W S 2 0 0 0 •ользуют внутренние о ч е р е д и О С . П р о м е ж у т о ч н ы е д р а й в е р ы Кут передавать п а к е т ы н а б о л е е н и з к и й у р о в е н ь п о с л е о п р е д е ляя стека для этого д р а й в е р а ( i / o s t a c k l o c a t i o n ) , а т а к ж е ф о р ipwT функцию iocompletion д л я с в я з и с д р а й в е р а м и в е р х н е г о вяя. Когда вызывается
driverentry,
функция
она
устанавливает
)»саdispatch ф у н к ц и й , startio ( е с л и о н а е с т ь ) и u n l o a d ( е с л и о н а II): Dmobject->majorfunction[irp_mj_xxx] I
=
Dimobject->majorfunction[irp_mj_yyy]
dddispatchxxx; =
dddispatchyyy;
Driverobject->driverstartio = ddstartio; Dcmcbjecl->dwerunload = ddunload;
I
Также определяется а д р е с ф у н к ц и и
adddevice,
в
driverexten-
m Driverobject->driverextension->adddevice = ddadddevice;
!
Драйвер может з а д а т ь н е с к о л ь к о d i s p a t c h ф у н к ц и й , н о т о л ь -
ытоодной функции т и п а startio,
adddevice и
unload.
Большинство д р а й в е р о в и м е ю т п о л е р а с ш и р е н и я ( d e v i c e е х •Ьл) в объекте у с т р о й с т в а . Э т о п о л е с о д е р ж и т и н ф о р м а ц и ю , (цифичную для д а н н о г о у с т р о й с т в а , и х р а н и т у к а з а т е л и н а р е ки, выделенные в р а з н ы х ф у н к ц и я х . Дополнительно
к
функциям
dispatch,
adddevice,
startio
и
«ted стандартный д р а й в е р с и с т е м ы в к л ю ч а е т о б р а б о т ч и к п р е рланш —
Interruptservice
(isr).
Драйверы
для
физических
тройств должны и м е т ь о б р а б о т ч и к и п р е р ы в а н и й , i s r д о л ж е н з а кировать прерывания ( C L I ) . З а т е м о н в ы п о л н я е т н е о б х о д и м ы е ерации, связанные с с о х р а н е н и е м т е к у щ е г о с о с т о я н и я . Д а л е е 385
необходимо положить пакет в очередь к нижестоящему дрийкрт. Они выполняются с с а м ы м высоким уровнем приоритета flptiверы, которые имеют обработчики прерываний, также должны иметь dpc-функции и л и специализированные фс-функцип спацнально д л я обработчиков прерываний {Dpcforisr). Средства синхронизации д л я д р а й в е р о в Любой драйвер устройства, к о т о р ы й разделяет данвые • своими обработчиками прерываний, д о л ж е н использовать средства синхронизации с учетом многопроцессорных систеы. Драйверы, в которых п а к е т ы могут оставаться в очерелх неопределенное время, д о л ж н ы иметь средства удаления этих news тов (документы на печать). Д л я этого используется клессфуякцн! типа cancef д л я выполнения запроса на удаление необработанных пикетов. П р и м е р а м и драйверов, к о т о р ы е обязательно должен иметь ф у н к ц и и этого класса, я в л я ю т с я клавиатура, мышь, параллельный и последовательный порты (или драйверы, находнщнкл над ними) и драйверы ФС. Д р а й в е р устройство, к о т о р ы й д о л ж е н работать иеоосргг стванно с контроллерами устройств, м о ж е т иметь функцию i ж cacontrollercontrol. WDM-драйвер не м о ж е т иметь функция этот класса. Драйверы верхнего уровня, которые не используют вакети для связи с н и ж е с т о я щ и м и драйверами, могут иметь одну ид несколько ф у н к ц и й завершения. Драйверы верхнего уровня которые используют п а к е т ы д л я передачи запроса нижестоящем; драйверу, д о л ж н ы иметь ф у н к ц и ю з а в е р ш е н и я типа locomplebon. Функции д л я работы со временем (lotimer) Д р а й в е р ы , которые д о л ж н ы проверять время выполнена операций ввода-вывода с целью определения превышения времени о ж и д а н и я (непример, в вяектронной почте время ожвдняи передачи электронного письма — timed out), которые должны г.? риодически обновлять какие-то переменные (такие как счетчап) должны иметь ф у н к ц и и этого класса. Ф у н к ц и я для работы со арб менем - это dpc-функция, онн относится к объекту устройства, и I / 0 - M a n a g e r вызывает одии раз в секунду. Драйвер может имен функцию д л я работы со временем д л я каждого объекта устро!ства, который он создаетД р а й в е р ы , к о т о р ы м необходимо в ы з ы в а т ь функцию дла реботы со временем ч а щ е чем один раз в секунду или интервалы 386
ова могут быть п е р е м е н н ы м и , и с п о л ь з у ю т ф у н к ц и и к л а с с а IpVmtimerdpc в м е с т о lotimer ф у н к ц и й .
Драйвер может иметь
иг или несколько ф у н к ц и й э т о г о к л а с с а н а р я д у с ф у н к ц и я м и 1 caiotimer.
I Custcmdpc Напоминаем, что о б р а б о т ч и к и п р е р ы в а н и й д р а й в е р а и м е ю т мыйвысокий уровень п р и в и л е г и й . Ч т о б ы н е б л о к и р о в а т ь р а б о рсвстемы в целом, э т и о б р а б о т ч и к и д о л ж н ы в ы п о л н я т ь с я о ч е н ь стро, поэтому они р а б о т а ю т т о л ь к о с р а з д е л я е м ы м и д а н н ы м и , |в остальные о п е р а ц и и в ы п о л н я ю т с я с п о м о щ ь ю с п е ц и а л ь н о г о сса функций c u s t o m d p c , к о т о р ы е в ы п о л н я ю т с я у ж е н а б о л е е кон уровне п р и в и л е г и й . П р и м е р о м т а к и х ф у н к ц и й я в л я ю т с я лкции, работающие с о в р е м е н е м п о с л е в ы х о д а и з о б р а б о т ч и к а срываний для т а й м е р а . Любой драйвер, к о т о р ы й д о л ж е н в ы п о л н я т ь о п е р а ц и ю и н и Иишзации н а р а з л и ч н ы х э т а п а х и с п о л ь з о в а н и я , д о л ж е н и м е т ь кщш класса reinitialize. СЕКЦИИ
Ф у н к ц и я reinitialize
вызывается после
driverentry.
Любой драйвер у с т р о й с т в а , к о т о р ы й и с п о л ь з у е т п р я м о й д о тга к памяти (dma), м о ж е т и м е т ь ф у н к ц и ю к л а с с а adaptercontrol, аюрая управляет п е р е д а ч е й д а н н ы х м е ж д у у с т р о й с т в о м и ф и з и •г'кой памятью ч е р е з к о н т р о л л е р dma. I Напоминаем, что к а ж д ы й д р а й в е р д о л ж е н и м е т ь ф у н к ц и ю liverentry, которая и н и ц и а л и з и р у е т с т р у к т у р ы д а н н ы х и р е с у р "•.I/0-Maiiager в ы з ы в а е т ф у н к ц и ю driverentry, к о г д а о н з а г р у ж а Ьаивер. В драйвере,
Е
который
поддерживает
plug
and
play {PNP)1,
г,ъкция driverentry о т в е т с т в е н н а за и н и ц и а л и з а ц и ю д р а й в е р а , кция adddevice ( и , ляет запросом
рпр
возможно, irp
функция
mnstart_device)
dispatch,
которая
ответственна
за
илизацию у с т р о й с т в а . И н и ц и а л и з а ц и я д р а й в е р а в к л ю ч а е т
: т инициализацию о б ъ е к т о в ,
которые использует драйвер,
1шемных ресурсов, к о т о р ы е з а в и с я т о т д р а й в е р о в ( п о р т ы , в е к Ьы прерываний). Эта функция м о ж е т и м е т ь и м я , о т л и ч н о е от driverentry, д р а й ц задает это имя к о м п о н о в щ и к у . К о м п о н о в щ и к д о л ж е н з н а т ь шстартовой ф у н к ц и и д л я п е р е д а ч и э т о г о а д р е с а з а г р у з ч и к у ОС. "|умолчанию имя — driverentry. ишы поддерживать все современные драйверы.
387
370
Е с л и ф у н к ц и я driverentry в о з в р а щ а е т что-то оттичяое crrsfesuccess, то драйвера в п а м я т и не остается. Ф у н к ц и я driverentry, к о т о р а я з а в е р ш а е т с я с ошибкой, д » на освободить все с и с т е м н ы е о б ъ е к т ы » с и с т е м н ы е ресурсы, ре естр, к о т о р ы е б ы л и з а н я т ы до о б н а р у ж е н и я ошибки. Ова до.нкш о ч и с т и т ь т а б л и ц у адресов о б р а б о т ч и к о в в объекте драйвера дла irp_mj_flush_buffers и / и л и irp_mj_shutdown, если драйвер лодд . ж н в а е т эти запросы- Эта ф у п к ц и я д о л ж н а т а к ж е занести зе^лг в ж у р н а л п е р е д в ы х о д о м из ф у н к ц и и . Е с л и д р а й в е р имеет свой п о т о к и л и ж д е т какой-то объеме, ф у н к ц и я dnverentry м о ж е т и н и ц и а л и з и р о в а т ь dispatcber-i&bt*-^, которые ждут, вызывая соответствующие функции кетЬ • с и с п о л ь з о в а н и е м с о б ы т и я , с е м а ф о р а , m i i t e x и объектов epei Т а к к а к с т а р т о в а я ф у н к ц и я в ы п о л н я е т с я к а к системвып * т о к , ф у н к ц и я сама м о ж е т ж д а т ь в течение некоторого илтершЗ dispelcher-оЬъекта, к о т о р ы й д о л ж е н б ы т ь инициализировав д< того, к а к н а ч а л о с ь о ж и д а н и е . С о с т о я н и е з а в е р ш е н и я о п р е д е л я е т успешность инициал* зации. К а к сказпно в ы ш е , все с т р о к и д л я драйверов задаются вф | м а т е Unicode. Т и п д а н н ы х д л я э т о й с т р о к и определен ниже: tus
typedef struct _unicode_string { ushort length: ushort maximumiength. pwstr buffer. } unicode slring 'punicode_strlng; К а к в и д н о и з з а д а н и я с т р о к и , д л я н е е задается текущаа д л и н а в б а й т а х (ushort length). м а к с и м а л ь н а я длина в байтах hort maximumiength) и адрес буфера д л я з а п и с и этой строки (pwstr buffer). Е с л и с т р о к а и м е е т н у л е в о й з а в е р ш и т е л ь , то поле Isngtfr не у ч и т ы в а е т этого с и м в о л а . 9.5-9. Особенности выделения памяти в драйверах Т я к к а к во в р е м я з а г р у з к и д р а й в е р а страничный режим илж е т б ы т ь не в к л ю ч е н , н е л ь з я и г п о л ь з о в п т ь стандартныефув i ОС и т е м более я з ы к а д л я р а б о т ы с п а м я т ь ю . Д л я выделения пазити используется ф у н к ц и я exallocatepool: PVOID
):
exallocatepooK in pootjtype pooltype. in size_t numberofbytes
Функция в ы д е л я е т п а м я т ь т р е б у е м о г о т и п а и в о з в р а т ц а а д р е с выделенной п а м я т и . Э т а ф у н к ц и я и с п о л ь з у е т с я д л я МЕНЯ памяти в п у л е ( о б л а с т и п а м я т и я д р а ) . Т и п п а м я т и тая одной
из
следующих
oolmustsucceed, Blignedmusts,
констант:
Nonpagedpool,
nonpagedpoolcachealigned, pagedpool,
поп-
nonpagedpool-
pagedpoolcachealigned.
Константы
'деляют страничный и н е с т р а н и ч н ы й п у л ы , с в ы р о в н е н н ы м и решенными
адресами.
Поле
Numberofbytes
задает
коли-
т о выделенной п а м я т и . Е с л и т и п п а м я т и з а д а н к о н с т а н т о й immusts(ucceed),
она у с п е ш н о з а в е р ш а е т с я ,
если система
Iдостаточно с в о б о д н о й п а м я т и , ф у н к ц и я в о з в р а щ а е т а д р е с тенной области
памяти.
Функция
exallocatepool в о з в р а щ а е т
з тип памяти не р а в е н xxxmusts(ucceed) и н е т д о с т а т о ч н о г о асвободной п а м я т и д л я у д о в л е т в о р е н и я э т о г о з а п р о с а . Е с л и [ргае количество б а й т о в > = р а з м е р а с т р а н и ц ы , т о в ы д е л я > буфер, выровненный н а г р а н и ц у с т р а н и ц ы . Е с л и т р е б у е м ы й е р памяти < = р а з м е р а с т р а н и ц ы , б у ф е р н е п е р е с е к а е т г р а н и ниц. Эти з а п р о с ы в с е г д а в ы д е л я ю т п а м я т ь , в ы р о в н е н н у ю ицу 8-байтной г р а н и ц ы . Д л я т и п а п у л а ,
р а в н о г о попра-
lolwustsucceed, и н о г д а д о с т у п н ы м и я в л я ю т с я о б л а с т и р а з si менее страницы. В с л у ч а е о ш и б к и в ы д е л е н и я п а м я т и и з - з а пяточного размера п а м я т и п о ф у н к ц и и exallocatepool н а с т у 1 крах системы. П о э т о м у з а п р о с д а н н о г о т и п а п а м я т и д о л ж е н олняться лишь в к р а й н е м с л у ч а е . Т о л ь к о н е с к о л ь к о т и п о в 1еров могут делать т а к и е з а п р о с ы . З а п р о с н а в ы д е л е н и е п а I с размером м е н е е р а з м е р а с т р а н и ц ы в н е с т р а н и ч н о м п у л е иется благополучно. В с л у ч а е и с п о л ь з о в а н и я с т р а н и ч н о г о и теряются н е и с п о л ь з о в а н н ы е в с т р а н и ц е б а й т ы , к о т о р ы е ись от предыдущего в ы д е л е н и я . В ы д е л е н и е п а м я т и д о л ж н о литься на уровне п р и в и л е г и й irql <= dispatch_level. У р о в е н ь ишегаи dispatchjevel д о л ж е н и с п о л ь з о в а т ь с я д л я т и п а п а м я mpagedxxx. В о в с е х д р у г и х с л у ч а я х д о л ж е н и с п о л ь з о в а т ь с я Жь привилегии irql Если функция
<
dispatch jevel.
выделения
1, должен в о з в р а щ а т ь с я
памяти
код
exallocatepool
возврата
ntstatus
возвраща=status_insuffi-
I„resources или о б р а б о т к а д о л ж н а б ы т ь о т л о ж е н а д о т е х п о р , взапроссможет быть в ы п о л н е н .
389
9.6. Пример д р а й в е р а и программы для использования д р а й в е р а 1 9.6.1. Текст д р а й в е р а П р и м е р . С о з д а т ь д р а й в е р д л я в ы в о д а с т р о к и и определены параметров винчестера (чтения MBR)Z. О с н о в н ы е ф у н к ц и и д л и д р а й в е р а о п р е д е л е н ы в ЗАГОЛОВОЧНОМ ф а й л е N T D D K . H , к о т о р ы й п о с т а в л я е т с я в м е с т е с N T DDK поэтом у э т о т в а г о л о в о ч н ы й ф а й л д о л ж е н б ы т ь п о д к л ю ч е н к основами файлу драйвера: #tndude
Н а п и с а н и е д р а й в е р а с л е д у е т н а ч а т ь с определения твы у с т р о й с т в а , д л я к о т о р о г о с о з д а е т с я д р а й в е р . К а ж д о м у устройств с о о т в е т с т в у е т о п р е д е л е н н ы й н о м е р . Н о м е р а у с т р о й с т в опре; -пен ы в ф а й л е N T D D K - H . П о д н о м е р у с т р о й с т в а отводится чгтыр» б а й т а . Н о м е р а у с т р о й с т в в и н т е р в а л е 0 - 3 2 7 6 7 зарезервированы ф и р м о й M i c r o s o f t д л я с о б с т в е н н о г о и с п о л ь з о в а н и я . Номера 32768 6 5 5 3 5 м о ж н о и с п о л ь з о в а т ь д р у г и м р а з р а б о т ч и к а м драйвере!. Д л я с о в р е м е н н ы х в е р с и й д р а й в е р а н о м е р а б о л ь ш е 65535 н е г п о л ь з у ю т с я . П р и м е р ы н о м е р о в у с т р о й с т в п р и в е д е н ы в табл 9 2. Таблица Константы д л я о п р е д е л е н и я некоторых устройств в зависимости от их тнпа Имя константы
г/п
попета nv
-
2
1
91
0*00000001
1
FILE_DEVICEBEEP
2
FILE_DEVICE_CD_ROM
3
FILE_DEVICE_CD
4
FILE_DEVtCE_FILE
5
FILE_DEV/CEKEYBOARD
ОхОООООПОВ
в
FILEDEVI
OxOOUOOOOF
0x000(10002
ROM
FILE
SYSTEM
CE_MOUSE
SYSTEM
охоооооооэ 0x00000009
370 1 Текст драйвера создан на основе драйвера нз Microsoft JOUTDRI |M3J). ПЮТС" остдвлеп комментарии с укязанвем пптора драй нерв. 2 Выше рассматривалось использовании системного драйвера ала лтжх KCJKL Нопомянаем, что доступ к системному драйверу имеет только оодыоммаа с правеми ялминисгрптора. Созданный драйвер позволит выволиять try опгр« цпю для любого вользователн.
Продолжение Л
I
табл.
9.2
2 FILE DEVICE NETWORK
0x00000012
FILE DEVICE NETWORK FILE SYSTEM
0x00000014
I' 1IFILE D DEVICE PRINTER
0x00000018
I FILE DEVICE UNKNOWN
0x00000022
Jl | FILE_DEVICE_MODEM
0x0000002b
Тип 0x00000022 и с п о л ь з у е т с я в т о м с л у ч а е , е с л и о п р е д е л я е т драйвер для нового т и п а у с т р о й с т в а и л и в о о б щ е н е д л я у с т р о й "S. Так как с о з д а в а е м ы й д р а й в е р я в л я е т с я и н ф о р м а ц и о н н ы м I не предназначен д л я у п р а в л е н и я к о н к р е т н ы м т и п о м у с т р о й ему поставлен
в
соответствие
идентификатор
FILE_DEVICE_
WI0WN: Шпе IOCTL_UNKNOWN_BASE
FILE_DEVICE^
UNKNOWN
Для доступа к д р а й в е р у в п о л ь з о в а т е л ь с к о м р е ж и м е н е о б х о о определить к о д ы ф у н к ц и й , к о т о р ы е б у д у т и с п о л ь з о в а т ь с я ушщни DeviceloControl. Д л я ф о р м и р о в а н и я э т и х к о д о в и с п о л ь хямакрос CTL_CODE и з ф а й л а N T D D K . H : IIКобы функций с номерами 0-2047 зарезервированы за фирмой //Microsoft IIКоды 2048-4095 можно использовать разработчикам драйверов. Шпе CTL CODE (DeviceType, Function, Method, Access) ( I ((DeviceType) « 16) | ((Access) « 14) | ((Function) « 2) | (Method) I
J I DeviceType — б е р е т с я и з т а б л . 9 . 2 ; Function — н о м е р м о ж е т б ы т ь о п р е д е л е н в и н т е р в а л е 2 0 4 8 95(0x800..0x8FF); Method — задает м е т о д и с п о л ь з о в а н и я б у ф е р и з а ц и и п р и в в о д е иоде. Методы и с п о л ь з о в а н и я п р е д с т а в л е н ы в ф а й л е N T D D K . H . шно
используется
METHODBUFFERED;
kcess — р е ж и м д о с т у п а . О п р е д е л я е т р е ж и м ы д о с т у п а . Т а к , как в вызове CreateFile, д л я и с п о л ь з о в а н и я д р а й в е р а д о л ж н ы iTbзаданы режимы ч т е н и я и з а п и с и , д л я д р а й в е р а д о л ж н ы б ы т ь сетыFILE
READ
ACCESS
и
FILE_WRITE_ACCESS.
Определим м а к р о с ы д л я з а д а н и я с л е д у ю щ и х ф у н к ц и й : 391
//Функция для вывода строки из драйвера в пользовательском //режиме ttdefine IOCTL_MSJDRVR_CET__STRINC CTLCODEI (IOCTLUNKNOWNBASE, 0x0800, METHOD BUFFERED 1 FILE_READ_ACCESS | FILE_WRITE_ACCESS) // Функция для чтения MBR винчестера ttdefine IOCTL MSJDRVR READ_MBR CTL CODE 1 (IOCTL UNKNOWN BASE, 0x0801, METHOD BUFFERED, I FILE_ REA DA CCESS \ FILE_WRITE_ACCESS) #define IOCTL_UNKNOWN_BASE FILE_DEVICE_UNKNOWN В с е ф у н к ц и и д р а й в е р а д о л ж н ы и м е т ь о д и н а к о в ы й префикс. Д л я с о з д а в а е м о г о д р а й в е р а в к а ч е с т в е п р е ф и к с а б у д е м использовать M S J . О п р е д е л и м з а г о л о в к и ф у н к ц и й драйвера:
void MSJUnloadDriver(PDRIVEROBJECT DriverObject); NTSTATUS MSJDispatchCreatefIN PDEVICEJOBJECT DeviceOb/ect IN PIRP Irp); NTSTATUS MSJDispatchCtose(IN PDEVICEOBJECT DeviceObject IN PIRP Irp); NTSTATUS MSJDispatchloctl(IN PDEVtCEjOBJECT DeviceObject IN PIRP Irp); О п р е д е л и м г л а в н у ю ф у н к ц и ю д р а й в е р а (DriverEntry).
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRINC RegistryPath) { NTSTATUS ntStatus: UNICODE_STRING uszDriverStringUNICODESTRING uszDeviceString; PDEVtCEjOBJECTpDeviceObject; //Задание имени драйвера должно совпадать с именем файла // для драйвера RtllnitUnicodeStringf&uszDriverStririg, L' WDeviceWMSJDrvr); //Создание объекта типа устройство ntStatus = loCreateDevice(DriverObject, О, &uszDriverString, Ft LE_ DEVtCE_ UN К NO WN 0, FALSE &pDeviceObject) if(ntStatus != STATUS_SUCCESS) return ntStatus; //Определение имени устройства для заданного драйвере RtllnitUnicodeStringf&uszDeviceString, U'WDosDevicesWMSJDrvf) //Задание связи между именами драйвера и устройства ntStatus = loCreateSymbolicLinkf&uszDeviceString, &uszDnverString), iffntStatus != STATUS_SUCCESS) { // Удаление созданного устройства loDeleteDevice(pDeviceObject); return ntStatus; } 392
//Построение
таблицы
функций
DmrObject->DhverUnload = MSJUnloadDriver; DriverObject->MajorFunction[IRP_MJ_CREATE] = MSJDispatchCreate; DrmObject->MajorFunction[IRP_MJ_CLOSE] = MSJDispatchClose; merObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= MSJD'ispatchloctl; IIВыход из функции return ntStatus;
I //Определение остальных функций драйвера NTSTATUS MSJDispatchCreate(IN PDEVICE_OBJECT DeviceObject, INPIRPIrp) { II Заполнение полей стандартного пакета Irp lrp->loStatus.Status = STATUS_SUCCESS; lrp->ioStatus.lnformation=0; loCompleteRequestflrp, IO_NOJNCREMENT); return (STATUS_ SUCCESS); I NTSTATUS MSJDispatchClose(IN PDEVICEjOBJECT DeviceObject, INPIRPIrp){ trp->loStatus. Status = STATUS_SUCCESS; trp->loStatus. lnformation=0; !oCompleteRequest(lrp, 10_ NO_ INCREMENT); return(STATUSSUCCESS); } IIЭта функция будет использоваться для чтения MBR NTSTATUS MSJReadDriveZeroMasterBootRecord(PUCHAR pBuffer) { NTSTATUS ntStatus; mCODE STRING uszDeviceName; PFILE OBJECT
fileObject;
PDEVICEOBJECT pDriveDeviceObject; //Определение устройства RtllnitUnicodeString(&uszDeviceName, PbysicalDriveO");
L"\\DosDevices\\
//Получение адреса объекта устройства для PhysicalDriveO ntStatus = toGetDeviceObjectPointerf&uszDeviceName, FiLEREADATTRIBUTES, &fileObject, 8
// Формирование запроса для операции чтения одного сектора //с номером 0. // Функция возвращает адрес стандартного пакета, в котором //записан запрос plrp = loBuildSynchronousFsdRequest(IRP_MJ_READ, pDriveDeviceObject, pBuffer, 512, §orNum, &event, &ioStatus): if(lplrp) return FALSE; //Вызов очередного драйвера с передачей ему пакета ntStatus = loCallDriver(pDriveDeviceObject, plrp); //Если запрос сразу не выполнен if(ntStatus == STATUS_PENDING) { //Ждем завершения выполнения запроса KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE NULL); ntStatus = ioStatus. Status; } //Проверка успешности завершения запроса if(!NT_SUCCESS(ntStatus)) return ntStatus; //Освобождение созданного объекта (счетчик уменьшается на 1. //если объект устройства не используется другими драйверами //то он уничтожается) ObDereferenceObject(fileObject); } return ntStatus } NTSTATUS MSJDispatchloctlflN PDEVICEJOBJECT DeviceObject IN PIRP Irp) { NTSTATUS ntStatus: PIO STACK LOCATION irpStack = loGetCurrentlrpStackLocation(lrp); switch(irpStack->Parameters. DeviceioControl. loControlCode) { case IOCTL_MSJDRVR_GET_STRING: strcpy(lrp->Associatedlrp.SystemBuffer, "Hello from NTKernel\n"): ntStatus = STATUS_SUCCESS; break; case IOCTL_MSJDRVR_READ_MBR: // Чтение MBR, если буфер достаточного размера if(irpStack->Parameters. DeviceioControl. OutputBufferLength >= 512) ntStatus = MSJReadDriveZeroMasterBootRecord(lrp-> Associatedlrp SystemBuffer); else ntStatus = STATUS_BUFFERJTOO_SMALL; break; default: break; } 394
!rp->loStatus. Status = ntStatus; Определение количества полученных байтов if/ntStatus == STATUS SUCCESS) lrp->loStatus.Information = irpStack-> Parameters DeviceloControl.OutputBufferLength, elselrp->loStatus.lnformation = 0; loCompleteRequestflrp, I0_ NOJNCREMENT); return ntStatus; )
mid MSJUnloadDriver(PDRIVER_OBJECT DriverObject) 9№C0DE_STRING uszDeviceString; II Удаление объекта №e!eteDevice(DriverObject->DeviceObject); IIРазрушение связи между объектом и драйвером RUInitUnicocleString(&uszDeviceString, L"\\DosDevices\ 1 MSJDrvr"); lcDeleteSymbolicLink(&uszDeviceString); I 9.6.2. Компиляция и к о м п о н о в к а д р а й в е р а Пусть файл, с о д е р ж и м о е к о т о р о г о о п р е д е л е н о в ы ш е , и м е е т KMSJDrvr.c. Д л я т р а н с л я ц и и э т о г о ф а й л а н е о б х о д и м о , к р о м е I, в текущий к а т а л о г п о л о ж и т ь с л е д у ю щ и е ф а й л ы : Файл SOURCES ( б е з р а с ш и р е н и я ) , с о д е р ж и м о е к о т о р о г о 1Жно быть:
WGETNAME=MSJDrvr TARGETPATH-obj TARGETTYPE-DRIVER SOURCES-MSJDrvr. с В этом файле з а д а е т с я : и м я д р а й в е р а ( с т р о к а 1 ) , к а т а л о г , да положить р е з у л ь т а т т р а н с л я ц и и ( с т р о к а 2 ) , т и п с о з д а в а е м о г о е д л я — драйвер ( с т р о к а 3 ) , и м я и с х о д н о г о ф а й л а ( с т р о к а 5 ) . Фтлmakefile, с о д е р ж и м о е к о т о р о г о д о л ж н о б ы т ь : I
# DO NOT EDIT THIS FILE!!! Edit Asources. if you want to add a new vice Utile to this component. This file merely indirects to the real make file tl that is shared by all the driver components of the WINDOWS NT DDK f !INCLUDE $(NTMAKEENV)\makefite.def 395
Э т о т ф а й л о п р е д е л я е т м е с т о р а с п о л о ж е н и я соответствующего ф а й л а
makefile.def, е с л и р а н е е о п р е д е л е н о NTMAKEENV
Дтя
о п р е д е л е н и я э т о й к о н с т а н т ы и н а с т р о й к и д р у г и х констант, кот о р ы е и с п о л ь з у ю т с я п р и к о м п и л я ц и и , н е о б х о д и м о , чтобы были у с т а н о в л е н ы N T D D K , V i s u a l S t u d i o . Д а л е е н е о б х о д и м о выбрать
Пуск-^Программы-tDevelopment Kits^WINDOWS 2000 DDK-* Checked Build Environment. В э т о м с л у ч а е н а с т р а и в а ю т с я все нео б х о д и м ы е к о н с т а н т ы . Д а л е е н е о б х о д и м о , и с п о л ь з у я командуC D — И з м е н и т ь к а т а л о г , п е р е й т и в т е к у щ и й к а т а л о г , г д е находятся ф а й л ы д р а й в е р а
(MSJDrvr.c,
makefile,
SOURCES),
и запустить
команду NTDDK1: build — cZ, к о т о р а я в ы п о л н я е т к о м п и л я ц и ю и к о м п о н о в к у драйвера. Драйвер i386\
—
MSJDrvr.sys
помещается
в
подкаталог
\objchk'
текущего каталога драйвера. 9.6.3. Использование д р а й в е р а Подготовка к з а г р у з к е и з а г р у з к а д р а й в е р а Д л я а в т о м а т и ч е с к о й з а г р у з к и д р а й в е р а в о в р е м я загрузки О С
п о м е с т и м е г о в с т а н д а р т н ы й к а т а л о г д л я д р а й в е р о в : C:\WIhNT
System32\DRIVERS.
Используя
редактор
реестра
д и м в реестре новый раздел с именем драйвера деле
RegEdit,
созда-
MSJDrvr в подраз-
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet
Sn
vices. Д л я с о з д а н н о г о р а з д е л а о п р е д е л и м с л е д у ю щ и е параметры DisplayName = MSJDrvr ErrorControl = 1 ImagePath = System32\DRIVERS\MSJDrvrsys Start = 2 Type = 1 П о с л е з а д а н и я э т и х п а р а м е т р о в в р е е с т р е в ы п о л н и т е перезагрузку компьютера для загрузки драйвера. Главная п р о г р а м м а для тестирования функций драйвера ttinclude #include ttinclude
<windows.h> <stdio.h> <winioctl.h>
1 Нельзя переходить в текущий каталог драйвера, используя стандартные файло вые менеджеры, так как после входа в менеджер теряются константы, сформированные при выполнении Пуск- /Программы -/Development Kits—>WI N DOWS 2000 DDK->Checked Build Environment.
396
Ш)пе IOCTL UNKNOWN BASE FILE_DEVICE__ UNKNOWN Шюе ЮСTL_MSJDRVR_GET_STRING CTL_CODE\ (i\OCTL_UNKNOWN_BASE, I Ш800. METHOD_BUFFERED, FILE_READ_ACCESS \ FILE WRITE_ACCESS) #define IOCTL MSJDRVR READ MBR 1 CTL CODE(IOCTL_UNKNOWN_BASE, 0x0801, METHOD BUFFERED,I FILE_ READ_ACCESS | FILE_ WRITE ACCESS) IIОтмена выравнивания внутри структуры Upragma pack(1) typedef struct tagPartitionlnfo I UCHAR ucActivePartFlag; // Флаг активности раздела UCHAR ucDH; //Адрес начала раздела в формате: сторона, //дорожка, сектор UCHAR ucCL; UCHAR исСН; UCHAR исТуре; // Тип раздела UCHAR ucEndDH; //Адрес конца раздела в формате: сторона, //дорожка, сектор UCHAR ucEndCL; UCHAR ucEndCH; DWORD dwLba; //Номер первого сектора раздела DWORD dwSize; II Размер раздела в секторах }PART_INFO, *PPART_INFO; fypedef struct tagMBR ( UCHAR ucBootProgramAndData[Ox1be]; //Загрузчик PARTJNFO Partlnfo[4]; // Таблица для 4 разделов USHORT usSignature; //MBR signature подпись раздела 0xaa55 jMBR, *PMBR; §pragma pack() //Функция для вывода информации о разделе void DisplayPartitionlnfo(PMBR pMbr) I char szOutput[256]; charszTemp[80]; Mi; sprinlf(szOutput,"MBR Signature: Ox%x\n\n",pMbr->usSignature); strcatfszOutput, "# A dive I tTyp e! tStarting CHS Ending CHS\tStart\ tLengthln"); fcr(i-C; i<4; i++) { sprintffszTemp,"%1 d %s\t%1d\t%04d %02d %02d %04d %02d %02d\ t%ld\t%ld\n", i+1, (pMbr->Partlnfo[i].ucActivePartFlag) ? "Yes": "No", 397
pMbr->Partlnfo[i].ucType, ((pMbr->Partlnfo[i].ucCL & OxcO)« 2) \ (USHORT)(pMbr->Partlnfo[i].ucCH), pMbr->Partlnfo[i].ucDH, pMbr->Partlnfo[i].ucCL & Ox3f, ((pMbr->Partlnfo[i].ucEndCL & OxcO) «2) (pMbr->Partlnfo[i].ucEndCH), pMbr->Partlnfo[i].ucEndDH, pMbr->Partlnfo[i].ucEndCL & 0x3f. pMbr->Partlnfo[i].dwLba, pMbr- >Partlnfo[i], dwSize); strcat(szOutput.szTemp); } MessageBox(0.szOutput."Disk 0 Partition Information",MB_OK); } int mainQ { HANDLE hDevice = CreateFile("\\\\ WMSJDrvr", GENERIC_READ\ GENERICWRITE, FILEJSHARE READ \ FILE_SHARE_WRITE 0, OPEN_EXISTING, 0, 0); if(hDevice == INVALID_HANDLE_VALUE){ LPVOID IpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER\ FORMAT MESSAGE EROM SYSTEM, NULL, GetLastError(). MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); MessageBox( NULL, (const char *)lpMsgBuf, "GetLastError", MB_OK\MB_ICONINFORMATION ); LocalFree( IpMsgBuf); } //Проверка функции вывода строки, char szString[256]; DWORD dwBytesRetumed = sizeof (szString); OVERLAPPED ov={0}; ov.hEvent = CreateEvent(NULL, TRUE, FALSE. NULL); bool bReturnCode = DeviceloControl (hDevice, IOCTL_MSJDRVR__GET_STRING. 0. 0,szString, sizeof(szString), &dwBytesReturned, &ov); bReturnCode= GetOverlappedResultfhDevice, <&oi/, &dwBytesReturned, TRUE); CloseHandle (ov. hEvent); if (bReturnCode) {//Все в порядке szString[dwBytesReturned] = 0; MessageBox (0, szString, "Message", 0);
}
else
MessageBox (0, "Error read, "Error", 0); //Проверка функции чтения MBR { DWORD dwBytesRetumed; BOOL bReturnCode = FALSE; 398
LAPPED
ov-{0};
HER data;
.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); iirnCode = DeviceloControl(hDevice,
IО CTL_ MSJDRVR_ RE A D_MBR, 0, 0 Sdala, sizeof(data), &dwBytesReturned, &ov);
PeturnCode= GetOvertappedResultfhDevice, &ov, DwBytesRetumed, TRUE); seHandle(ov.hEvent); ayPartitiontnfo(&data);
J Handle
(hDevice);
return 0;
9.6.4. Динамическая з а г р у з к а драйверов Используется д л я п р о г р а м м н о й з а г р у з к и д р а й в е р о в с п о м о омпонента О С м е н е д ж е р а с л у ж б ( s e r v i c e c o n t r o l m a n a g e r —
q. OpenSCManager
кция
спользуется д л я у с т а н о в к и с в я з и с м е н е д ж е р о м с л у ж б н а машине и о т к р ы в а е т е г о б а з у д а н н ы х .
HANDLE OpenSCManager( LPCTSTR IpMachineName, LPCTSTR IpDatabaseName, //pointer to database name string DWORD dwDesiredAccess // type of access
'achineName — и м я м а ш и н ы ,
если задано 0 или пустая
, то используется л о к а л ь н а я м а ш и н а ; atabaseName — и м я б а з ы д а н н ы х S C M , е с л и р а в н о 0 , т о ьзуется база д а н н ы х , к о т о р а я п р и н я т а п о у м о л ч а н и ю DesiredAccess п а могут
—
тип
быть
доступа
заданы
C_WRITE, GENERIC
к
такие
SCM,
в
типы:
качестве
типа
GENERIC_READ,
EXECUTE.
акция в о з в р а щ а е т 0 в с л у ч а е о ш и б к и и д е с к р и п т о р б а з ы хв случае у с п е х а . кция
CreateService
ция п р е д н а з н а ч е н а д л я с о з д а н и я о б ъ е к т а т и п а « С л у ж фегистрации э т о г о о б ъ е к т а в р е е с т р е .
399
SCHANDLE CrealeService ( SC HANDLE hSCManager. LPCTSTR IpServiceNarm. LPCTSTR IpDisplayName. DWORD dwDesiredAccess. DWORD dwServlceType, DWORD dwStartType. DWORD dwErrorControl. LPCTSTR IpBinaryPethName. LPCTSTR IpLoadOrderGroup, LPDWORD IpdwTagld. LPCTSTR ^Dependencies, LPCTSTR IpSeryiceStertName. LPCTSTR IpPessword )• где: hSCManager — д е с к р и п т о р б а з ы д а н н ы х менеджере служб (service control manager — SCM), о п р е д е л я е т с я с помощью фуак ц и и OpenSCManager, см. 9 . 6 . 4 ; IpServiceName — и м я с л у ж б ы д л я SCM, и м я регнстро-чл ствительное, нельзя использовать символы \. /; IpDisplayName — и м я с л у ж б ы д л я п о л ь з о в а т е л я ; dwDesiredAccess р е ж и м ы д о с т у п а , в к а ч е с т в е режимов м о ж н о з а д а в а т ь т а к и е же р е ж и м ы , к а к и в предыдущей функои; dwServlceType — т и п с л у ж б ы , з н а ч е н и я т и п о в службы сире делены в табл. 9.3; dwStartType — о п р е д е л я е т , к о г д а с л у ж б а з а п у с к а е т с я , авали г и ч н о п а р а м е т р у S t a r t в р е е с т р е д л я д р а й в е р а . Р а з л и ч н ы е зващ ния параметра заданы в табл. 9.4; dwErrorControl — о п р е д е л я е т с е р ь е з н о с т ь о ш и б к и , анплоппн о п а р а м е т р у ErrorCcntroi в р е е с т р е д л я д р а й в е р а - Различные и»чения параметра заданы в табл. 9.5; IpBineryPathName — к а т а л о г ( п о л н ы й п у т ь ) , где ваходнте* файл с драйвером;
задает-
IpLoadOrderGroup — о п р е д е л я е т г р у п п у д л я драйвера, с я , е с л и н е с к о л ь к о д р а й в е р о в п р и н а д л е ж а т о д н о й группе 1 . Если р а в е н 0 и л и п у с т о й с т р о к е , т о с л у ж б а н е в х о д и т в группу. Спнсо г р у п п о п р е д е л е н в р е е с т р е по а д р е с у HKEY LOCAL MACHINI System\CurrentControlSet\Contro[\ServiceGroupOrder:
370 ' Драйверы помоща ют в одну группу, если они должны быть загружены поел* ui перед загрузкой других драйверов.
IpdwTagld — т э г о в ы й
идентификатор,
используется для
-'жб,входящих в г р у п п ы , е с л и н е о б х о д и м о о п р е д е л и т ь п о р я д о к «грузки внутри г р у п п ы . Э т о т п о р я д о к о п р е д е л е н в р е е с т р е п о игоесу:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Cont>i\GroupOrderList; IpDependencies — м а с с и в с т р о к , о т о б р а ж а ю щ и й и м е н а д р а й вов, о т которых з а в и с и т д а н н ы й д р а й в е р , к о т о р ы е д о л ж н ы б ы т ь гружены до э т о г о д р а й в е р а ; IpPassword — п а р о л ь д л я д о с т у п а к с л у ж б е . Таблица
9.3
Типы служб 1» It
Тип службы
Описание
SERVICE_WIN32_OWN_PROCESS
Д л я службы создается свой процесс
SERVICE_WIN32_SHARE_PROCESS
Данная служба выполняется в том же процессе, что и другие с л у ж б ы
[ 3 SERVICE KERNEL_DRI VER
Служба является драйвером ядра Служба является драйвером ФС
SERVICE_FILE_SYSTEM_DRIVER 1
'5 SERVICEJNTERACTIVE
PROCESS
Служба может выводить сообщения
'
Таблица 9.4 Значения « ID
; !'
параметра
Значение параметра dwStartType
dwStartType Описание
2
3
SERVICE_BOOT_START
Используется для драйверов устройств. Стартует при загрузке ОС
SERVICE_SYSTEM_START
Используется для драйверов устройств. Запускается системой ввода-вывода после загрузки и инициализации драйверов устройств и драйверов ФС
SERVICE_AUTO_STAR T
Используется для драйверов устройств или служб, которые автоматически запускает SCM при инициализации системы
I
I1
401
Продолжение табл. 9.4 3
2
1 4
SERVICE_DEMAND_START
И с п о л ь з у е т с я для драйверов у с т р о й с т в и л и с л у ж б , которые з а п у с к а ю т с я SCM, когда вызывае т с я ф у н к ц и я StartService
5
SERVICEDISABLED
И с п о л ь з у е т с я д л я драйверов у с т р о й с т в и л и с л у ж б , которые не запущены
Таблица 9-5 З н а ч е н и я п а р а м е т р а dwErrorControl № п/п
Значение параметра dwErrorControl
Описание
1
Z
3
1
SERVICE IGNORE
ERROR
О ш и б к а о т о б р а ж а е т с я в журнале, но о п е р а ц и я запуска службы продолжается
2
SERVICE NORMAL
ERROR
О ш и б к а о т о б р а ж а е т с я в журнале и на э к р а н выводится сообщение, но о п е р а ц и я з а п у с к а службы продолжается
3
SERVICE SEVERE
ERROR
О ш и б к а о т о б р а ж а е т с я в журнале. Е с л и р а н е е была записана конфиг у р а ц и я д л я успешного запуска, с л у ж б а з а п у с к а е т с я , иначе система п е р е з а г р у ж а е т с я , используя последн ю ю у с п е ш н у ю загрузку
4
SERVICE CRITICAL
ERROR
О ш и б к а о т о б р а ж а е т с я в журнале, е с л и это в о з м о ж н о . Система перезаг р у ж а е т с я , и с п о л ь з у я последнюю успешную загрузку
Ф у н к ц и я в о з в р а щ а е т О в с л у ч а е о ш и б к и и дескриптор созданной службы в случае успеха.
Функция StartService Ф у н к ц и я з а п у с к а е т с л у ж б у , к о т о р а я р а н е е б ы л а создана с помощью функции
CreateService (см.
9.6.4).
BOOL StartService( SC_HANDLE hService, DWORD dwNumServiceArgs. 402
LPCTSTR
*lpServiceArgVectors
hService — д е с к р и п т о р с л у ж б ы ; dwNumServiceArgs — к о л и ч е с т в о а р г у м е н т о в ; IpServiceArgVectors — м а с с и в п а р а м е т р о в . Функция
CloseServiceHandle
Используется д л я о с в о б о ж д е н и я п а м я т и д л я д е с к р и п т о р а f e i . Функция п р и м е н я е т с я , е с л и д о с т у п к д е с к р и п т о р у б о л ь (неяужен. BOOL
CloseServiceHandle(SC_HANDLE
hSCObject);
r.HSCObject — д е с к р и п т о р с л у ж б ы . Функция
ControlService
Посылает у п р а в л я ю щ и й к о д с л у ж б е BOOL ControlService( $C_HANDLE hService. DWORD dwControl, LPSERi/'l С E_ STATUS IpService Status
hService — д е с к р и п т о р с л у ж б ы ; WCortrol-
управляющий код. Значение управляющего кода
быть с т а н д а р т н ы м ( о п р е д е л е н о в т а б л . 9 . 6 ) и л и о п р е д е л е н о юателем. З а с т а н д а р т н ы м и к о д а м и з а к р е п л е н ы з н а ч е н и я :рвале0..127. П о л ь з о в а т е л ь с к и е к о д ы п р и н и м а ю т з н а ч е н и я рале 1 2 8 . . 2 5 5 . Е с л и з а д а е т с я п о л ь з о в а т е л ь с к и й к о д ,
то
1КЦ1ШХ с о з д а н и я и л и о т к р ы т и я с л у ж б ы н е о б х о д и м о з а д а т ь |6ут
SERVlCE_USER_DEFINED_CONTROL;
доступа
IpServiceStatus
—
адрес
начала
структуры
типа
SERVICE_
SMIL'S, в которой з а п и с а н о а к т у а л ь н о е с о с т о я н и е с л у ж б ы . О п р е ше структуры : typedef struct _SERVICE_STATUS
{
DWORD dwServiceType; // Тип службы. DWORD dwCurrentState; //
Текущее
Определен в табл. состояние.
// Определен в табл. DWORD dwControlsAccepted; // DWORD DWORD
dwWin32ExitCode; dwServiceSpecificExitCode;
DWORD dwCheckPoirit; 403
9.3
9.3
DWORD }
dwWaitHint;
SERVICESTATUS,
*LPSERVICE_STATUS; Таблица9£
О п р е д е л е н и е с т а н д а р т н ы х у п р а в л я ю щ и х кодов Лг» п/п
Описание
Значение
i
1
SERVICE STOP
CONTROL
Запрос на остановку службы. С л у ж б а д о л ж н а и м е т ь атрибут SER VICE S ТОР
2
SERVICE PAUSE
CONTROL
З а п р о с на п р и о с т а н о в к у службы. С л у ж б а д о л ж н а и м е т ь атрибут SERVICEPAUSECONTINUE
3
SERVICE CONTINUE
CONTROL
З а п р о с н а з а п у с к приостановленной с л у ж б ы . С л у ж б а д о л ж н а иметь атрибут 1 SERVICE_PAUSE_CONTINUE
4
SERVICE CONTROL INTERROGATE
З а п р о с н а о б н о в л е н и е с о с т о я н и я службы, в S C M . С л у ж б а д о л ж н а иметь атрибут SERVICEJNTERROGATE
5
SERVICE SHUTDOWN
Ф у н к ц и я ControlService завершается с о ш и б к о й , е с л и з а д а н этот код.
CONTROL
Таблица 9.7 Определение стандартных состояний службы № п/п
Описание
Значение
1
SERVICESTOPPED
С л у ж б а н е выполняется
2
SERVICESTARTPENDING
Служба запущена
3
SERVICE_STOP_PENDING
С л у ж б а остановлена
4
SE R
С л у ж б а исполняется
5
SERVICE_CONTINUE_PENDING
С л у ж б а в р е ж и м е ожидания
6
SERVICE_PA
П а у з а д л я с л у ж б ы н е закончена
7
SERVICE_PAUSED
VICE_RUNNING
USE_PENDING
Пауза для службы
Р а с с м о т р е н н ы е в ы ш е ф у н к ц и и п о з в о л я ю т у п р а в л я т ь загрузкой и выгрузкой драйвера программно. 404
В данном р а з д е л е м ы р а с с м о т р е л и о с о б е н н о с т и с о в р е м е н н ы х июеров, и з у ч и л и и х с о с т а в н ы е ч а с т и , в з а и м о д е й с т в и е м е ж д у рми частями о д н о г о д р а й в е р а и м е ж д у д р а й в е р а м и , а т а к ж е любы создания, к о м п и л я ц и и , з а г р у з к и и и с п о л ь з о в а н и я д р а й «ров.
9.7. Вопросы и з а д а ч и 1. Чем драйвер о т л и ч а е т с я от о б ы ч н о й п р о г р а м м ы ? 2. Как в драйвере р е а л и з у е т с я т р е б о в а н и е м н о г о п л а т ф о р м е н н о €ТИ?
3. Почему многопроцессорность н а к л а д ы в а е т д о п о л н и т е л ь н ы е требования к драйверам? 4. За счет чего в д р а й в е р е р е а л и з о в а н а н е з а в и с и м о с т ь о д н о г о с л о я от изменений в д р у г о м с л о е ? а. Какая информация и где з а д а е т с я д л я д р а й в е р о в ? Д а й т е х а р а к теристику к а ж д о г о п а р а м е т р а . б. Как выделить п а м я т ь п о д з н а ч е н и е к л ю ч а р е е с т р а , е с л и р а з м е р этой области п а м я т и з а р а н е е не и з в е с т е н ? I. Для чего используется ф у н к ц и я DeviceioControl? П р и в е д и т е пример использования э т о й ф у н к ц и и . 8. С помощью к а к и х у т и л и т м о ж н о п р о с м о т р е т ь с о с т а в д р а й в е р а ? 9. Назовите ф у н к ц и и «главной п р о г р а м м ы » д р а й в е р а . 10. Каково назначение о б ъ е к т а «Устройство» в д р а й в е р е ? II. В каком случае в д р а й в е р в х о д и т ф у н к ц и я AddDevice? Д л я ч е г о необходима эта ф у н к ц и я ? 12. Назовите о с н о в н ы е ф у н к ц и и , в х о д я щ и е в с о с т а в д р а й в е р а , и определите н а з н а ч е н и е э т и х ф у н к ц и й . 13. Каким образом п е р е д а е т с я и н ф о р м а ц и я м е ж д у д р а й в е р а м и ? 14. Проверьте в о з м о ж н о с т ь ч т е н и я - з а п и с и п о р т о в д л я ОС, к о т о р а я у вас установлен а ( н а п о м и н а е м , ч т о д л я э т о г о н е о б х о д и м о проверить содержи мое битов 1 2 - 1 3 р е г и с т р а ф л а г о в ) . Ч и с л о , з а п и с а н ное в этих битах, з а д а е т д о с т а т о ч н ы й у р о в е н ь п р и в и л е г и и д л я чтения-записи портов. 15. Изучите текст д р а й в е р а д л я ч т е н и я - з а п и с и с о д е р ж и м о г о п о р т о в {src\general\portio\sys\ в N T D D K ) . В ы п о л н и т е т р а н с л я ц и ю этого драйвера. Задайте н е о б х о д и м ы е д а н н ы е в р е е с т р е д л я з а г р у з к и драйвера во время з а г р у з к и ОС. И с п о л ь з у я п р о г р а м м у gpdread.c из каталога src\general\portio\gpdread, проверьте п р а в и л ь н о с т ь установки этого д р а й в е р а .
405
10. Я З Ы К И СЦЕНАРИЕВ
Цели изучения раздела: 1 Описать основной набор команд, предоставляемы* ОС. 2. Продемонстрировать типичные функции языка сценариев и их не пользование в программировании. 3. Описать механизм реализации языков сценариев и роль этмхыы ков в реализации и интеграции системы 4 Написать небольшой сценарий с передачей параметров
В н а с т о я щ е е в р е м я п о н я т и е я з ы к а с ц е н а р и е в я в л я е т с я весьм а р а з н о с т о р о н н и м . В л и т е р а т у р е м о ж н о н а й т и определение язык а H T M L к а к я з ы к а с ц е н а р и е в , я з ы к V B S C R I P T н т . д . В днпнои у ч е б н о м п о с о б и и р а с с м а т р и в а ю т с я я з ы к и , г п о м о щ ь ю которых м о ж н о в ы п о л а и т ь о т д е л ь н ы е ф у н к ц и и о п е р а ц и о н н о й системы и л и н а с т р о и т ь е е п а р а м е т р ы . В б о л ь ш и н с т в е и н т е р а к т и в н ы х сяс т е м и н т е р ф е й с с п о л ь з о в а т е л е м О С о с н о в а н н а использовании командных языков. Командный язык - э т о я з ы к , в а которой пользователь взаимодействуете системой.
10.1. Языки сценариев и их роль С ц е н а р и и и с п о л ь з у ю т с я с ц е л ь ю т о н к о й н а с т р о й к и парамет р о в О С д л я к о н к р е т н о г о п о л ь з о в а т е л я . О н и п о з в о л я ю т в о время р е г и с т р а ц и и к о н ф и г у р и р о в а т ь а п п а р а т н ы е и п р о г р а м м н ы е средс т в а в с о о т в е т с т в и и с п о т р е б н о с т я м и к о н к р е т н о г о пользователя. О н и д а ю т в о з м о ж н о с т ь н а и б о л е е п о л н о и с п о л ь з о в а т ь возможвости ОС, о с о б е н н о н а с е р в е р а х , к о т о р ы е р а б о т а ю т б е з оператора. Так. д л я к а ж д о г о п о л ь з о в а т е л я м о ж н о з о д а т ь с ц е н а р и й его регистра370
в а сервере. Я з ы к с ц е н а р и е в б е р е т н а ч а л о с я з ы к а з а д а н и я в д н о й строки. Д л я с о в р е м е н н ы х О С я з ы к с ц е н а р и я п о з в о л я а д а в а т ь параметры, с р е д и о п е р а т о р о в я з ы к а е с т ь о п е р а т о р ы иного перехода и о п е р а т о р ы ц и к л а . Синтаксис з а п и с и к о м а н д з а в и с и т о т О С , н о о н и н т у и т и в н о тев и может б ы т ь л е г к о п р о ч и т а н , е с л и и з в е с т е н с и н т а к с и с |«икоманд д л я д р у г о й О С . Вданном у ч е б н и к е к р а т к о р а с с м а т р и в а ю т с я я з ы к с ц е н а р и е в т а й н ы е команды д л я О С W I N D O W S . Можно и с п о л ь з о в а т ь к о м а н д н ы е ( п а к е т н ы е ) ф а й л ы с р а с ш и и м RAT, как э т о б ы л о д л я D O S , и р а с ш и р е н и е м C M D , к а к д л я 2.Параметры з а д а ю т с я в в и д е % 1 , г д е I — ч и с л о 0 . . 9 , к о т о р о е ttKBoMepпараметра. П а р а м е т р с н о м е р о м 0 — э т о и м я в ы з ы в а чй программы. Основными о п е р а т о р а м и к о м а н д н о г о ф а й л а я в л я ю т с я : -системные к о м а н д ы О С ; -командные с т р о к и д л я в ы з о в а п р и л о ж е н и й ; -операторы б е з у с л о в н о г о и у с л о в н о г о п е р е х о д а д л я в ы п о л н и л и пропуска з а д а н н ы х с т р о к к о м а н д н о г о ф а й л а ; - оператор ц и к л а д л я м н о г о к р а т н о г о в ы п о л н е н и я о д н о й и л и рмкоманд к о м а н д н о г о ф а й л а .
10.2. Основные системные команды ОС WINDOWS Для получения в с е х с и с т е м н ы х к о м а н д д л я О С W I N D O W S гаюшо: -запустить и н т е р п р е т а т о р к о м а н д н ы х с т р о к О С W I N D O W S юенем CMD; - в консольном о к н е з а п у с т и т ь п р о г р а м м у H E L P > И м я ф а й л а . В этом с л у ч а е с п и с о к в с е х к о м а н д с и х к р а т н ы м о п и с а н и е м •jfiзаписан в ф а й л с з а д а н н ы м и м е н е м . Э т о т с п и с о к в о с н о в н о м зависит о т в е р с и и W I N D O W S . С п и с о к о с н о в н ы х к о м а н д д л я кущей версии W I N D O W S п р и в е д е н в т а б л . 1 0 . 1 . Таблица Список к о м а н д О С W I N D O W S йзмние команды 1
Описание команды ~
2
ШВ
Отображение и изменение атрибутов файлов
ML
В ы з о в о д н о г о п а к е т н о г о ф а й л а из д р у г о г о
407
10.1
Продолжение табл. 101 1
2
CD
В ы в о д и м е н и л и б о с м е н а т е к у щ е й папки
CLS
Очистка экрана
CONVERT
П р е о б р а з о в а н и е д и с к о в ы х томов ГАТ в NTFS. Н е л ь з я в ы п о л н и т ь п р е о б р а з о в а н и е текущего активного диска
COPY
К о п и р о в а н и е о д н о г о и л и н е с к о л ь к и х файлов в другое место
DEL
У д а л е н и е о д н о г о и л и н е с к о л ь к и х файлов
DIR
В ы в о д с п и с к а ф а й л о в и п о д п а п о к из указанной папки
DISKCOMP DISKCOPY
С р а в н е н и е с о д е р ж и м о г о д в у х г и б к и х дисков К о п и р о в а н и е с о д е р ж и м о г о о д н о г о гибкого диска на другой
EXIT
З а в е р ш е н и е р а б о т ы п р о г р а м м ы CMD.EXE ( и н т е р п р е т а т о р а к о м а н д н ы х строк)
FC
С р а в н е н и е д в у х ф а й л о в и л и д в у х наборов файлов и вывод р а з л и ч и й м е ж д у н и м и
HELP
В ы в о д и т с п р а в о ч н у ю и н ф о р м а ц и ю о командах WINDOWS
LABEL
С о з д а н и е , и з м е н е н и е и у д а л е н и е меток тома для дисков
MD или MKDIR
Создание папки
PATH
В ы в о д л и б о у с т а н о в к а п у т и п о и с к а исполняемых файлов
PAUSE
П р и о с т а н о в к а в ы п о л н е н и я п а к е т н о г о файла и вывод с о о б щ е н и я
RD, RMDIR
Удаление папки
REM
Комментарий в пакетном файле
SUBST
Ставит в с о о т в е т с т в и е з а д а н н о м у п у т и имя диска
VER
Вывод сведений о версии W I N D O W S 2000 Д л я п о л у ч е н и я п о м о щ и п о з а д а н н о й к о м а н д е достаточно
и с п о л ь з о в а т ь п а р а м е т р / ? , п о к о т о р о м у в ы в о д и т с я п о л н а я информ а ц и я о к о м а н д е . Н а п р и м е р , д л я п о л у ч е н и я п о м о щ и п о команде с р а в н е н и я д в у х ф а й л о в F C и с п о л ь з у е т с я к о м а н д а F C /?.
408
Результат в ы п о л н е н и я к о м а н д ы F C / ? , п е р е в е д е н н ы й н а p y e пш язык, приведен н и ж е . Сравнение д в у х и л и м н о ж е с т в а ф а й л о в и в ы в о д н а д и с п л е й ю ш й в них: FC[/A) [/С] [/L] [/LBn] [/N] [/Т] [/U] [/WJ [/пппп] [drivel :][path1]filename1 [drive2:][path2]filename2 FC /В [drivel:][path1]filename1 [drive2:][path2]filename2 /А — вывод т о л ь к о п е р в о й и п о с л е д н е й с т р о к , в к о т о р ы х о б н а жены различия. /В—допускается с р а в н е н и е д в о и ч н ы х ф а й л о в . /С — игнорируются р а з л и ч и я в р е г и с т р е б у к в . L — файлы с р а в н и в а ю т с я к а к A S C I I - т е к с т . /LBn — у с т а н а в л и в а е т с я м а к с и м а л ь н о е к о л и ч е с т в о о ш и б о к (строке. / N — выводить н о м е р а с р а в н и в а е м ы х с т р о к п р и с р а в н е н и и ffll-строк. /Т— не з а м е н я е т с и м в о л т а б у л я ц и и п р о б е л а м и . /(/— сравнение ф а й л о в в UNICODE. / W — пустые с и м в о л ы у б и р а ю т с я д л я с р а в н е н и я . /пппп — з а д а е т ч и с л о п о с л е д о в а т е л ь н ы х с т р о к , к о т о р ы е ажны быть п р о с м о т р е н ы после о ш и б к и . Для а д м и н и с т р и р о в а н и я и с п о л ь з у ю т с я к о м а н д ы с е м е й с т в а \1Ти планировщик к о м а н д A T . Для получения с п и с к а с е т е в ы х к о м а н д с е м е й с т в а NET н е о б одимо в командной с т р о к е н а б р а т ь к о м а н д у NET б е з п а р а м е т р о в , да получения и н ф о р м а ц и и о к о м а н д е н е о б х о д и м о н а б р а т ь NET 4ELP Команда. Примеры н е к о т о р ы х к о м а н д : НЕТ HELP ACCOUNTS По этой к о м а н д е в ы д а е т с я п о м о щ ь по к о м а н д е ACCOUNTS, вторая позволяет о п р е д е л и т ь о б щ е с и с т е м н у ю п о л и т и к у з а щ и ш - параметры п а р о л я п р и р е г и с т р а ц и и п о л ь з о в а т е л я ( м и н и ильная и м а к с и м а л ь н а я д л и н а , в р е м я ж и з н и и т . д . ) и п о в е д е н и е -етемы в случае в ы х о д а за з а д а н н ы е о г р а н и ч е н и я .
10.3. Написание сценариев, передача параметров 10.3.1. П р о с т е й ш и е с ц е н а р и и Рассмотрим н а п и с а н и е с ц е н а р и я д л я к о п и р о в а н и я о д н о г о файла в другой.
Д л я к о п и р о в а н и я необходимо и с п о л ь з о в а т ь команду COPY. Посмотрим п о м о щ ь по этой к о м а н д е с п о м о щ ь ю команды COPY/?' source
COPY[/V/[/NJ[/Y\/-Y][/Z][/A \ /В ) [/А\/В] [+ source [/А | /В] [+...)) [destination [/А | /В]}
source — з а д а е т ф а й л и л и ф а й л ы д л я копирования. /А — т е к с т о в ы е ф а й л ы с к о д и р о в к о й ASCII. /В — д в о и ч н ы е ф а й л ы . destination — и м я к а т а л о г а и л и ф а й л а - р е з у л ь т а т а . /V — п р о в е р я е т с я , что н о в ы й ф а й л з а п и с ы в а е т с я корректно. /Л/ — и с п о л ь з о в а т ь к о р о т к о е и м я ф а й л а , если копируются файлы с длинными именами. /У — в в о д и м ы й с и м в о л на з а п р о с ввода, если необходимо перезаписать файл. /-Y — п р и г л а ш е н и е к вводу на з а п р о с о перезаписи файла. fZ — к о п и р о в а н и е ф а й л о в по с е т и . К л ю ч / У м о ж е т б ы т ь з а д а н п е р е м е н н о й среды СОPYCMD. Он м о ж е т б ы т ь о т в е р г н у т п а р а м е т р о м /-Y в командной строк е . П о у м о л ч а н и ю з а п р о с ф о р м и р у е т с я , е с л и результирующий файл существует. Д л я о б ъ е д и н е н и я ф а й л о в в к а ч е с т в е исходного файла можно з а д а т ь м н о ж е с т в о ф а й л о в , н а п р и м е р , f i l e l + f U e 2 + file3, а в вачестве р е з у л ь т и р у ю щ е г о - один ф а й л . В э т о м с л у ч а е в результирую щ и й ф а й л з а п и ш у т с я з а д а н н ы е ф а й л ы в у к а з а н н о й последоытельности. Б у д е м и с п о л ь з о в а т ь в к о м а н д н о м ф а й л е 2 параметра. МуСору <src> <dest> К о м а н д н ы й ф а й л д л я к о п и р о в а н и я МуСору.Cmd: 1 вариант. Сору %1 %2 Недостаток ф а й л а : е с л и не с у щ е с т в у е т исходного файла — система в ы в о д и т сообщение па я з ы к е , п р и н я т о м по умолчании д л я ОС, к а к в ы п о л н и т ь э т у п р о в е р к у до в ы п о л н е н и я команды л вывести п о д с к а з к у п о л ь з о в а т е л ю ? 2 вариант ECHO OFF сIs If goto usage If "%2"=="goto usage If not exist %1 goto SrcError 370
If exist %2 goto DestError Copy %1 %2 >nil ECHO Благополучное выполнение Goto ok :Usage ECHO Usage.MyCopy Src Dest Goto OK :SrcError Echo Файл %1 не существует Goto OK Echo Файл %2 существует :0K
команды
копирования
Здесь и с п о л ь з о в а л и с ь д о п о л н и т е л ь н ы е к о м а н д ы , п о м о щ ь п о рорымможно п о с м о т р е т ь . Е с л и п а р а м е т р ы н е з а д а н ы , в ы в о д и т [ строка п о д с к а з к и с о б щ и м в и д о м к о м а н д ы ( U s a g e . M y C o p y Src ssl). Если р е з у л ь т и р у ю щ и й ф а й л с у щ е с т в у е т , с и с т е м а в ы д а е т цбщение
«Файл
<Итя
файла>
существует».
Если
параметры
-ДЙНЫ верно, то в ы п о л н я е т с я к о п и р о в а н и е ф а й л а и в ы д а е т с я пбщение
«Благополучное
выполнение
команды
копирования».
греваправление р е з у л ь т а т а р а б о т ы к о м а н д ы к о п и р о в а н и я в N I L вволяет подавить в ы в о д р е з у л ь т а т а в ы п о л н е н и я к о м а н д ы к о п и авання, ф о р м и р у е м ы й О С . Ю.3.2. Разветвления и ц и к л ы Простейшее р а з в е т в л е н и е в к о м а н д н о м ф а й л е у ж е р а с с м о jfaio в предыдущем п р и м е р е . З д е с ь м ы р а с с м о т р и м о б щ и е п р а в и .'I организации р а з в е т в л е н и й и ц и к л о в д л я к о м а н д н ы х ф а й л о в . I 1 этого более п о д р о б н о р а с с м о т р и м к о м а н д ы if, for и shift в к о жндных файлах. Команда IF В командном ф а й л е д о п у с к а е т с я и с п о л ь з о в а н и е к о м а н д ы : IF Условие Команда ш IF Условие Команда ELSE Команда. В качестве у с л о в и й з а д а ю т с я в ы р а ж е н и я в и д а 1 : if [not] errorlevel число команда [else выражение]; if [not] строка1==строка2 n
команда
[else
выражение];
if [not] exist имя_файла команда [else выражение]
Запись в квадратных скобках означает возможность отсутствия данного комвенть. 411
i f [ / i ] строка1 опсравнения строка2 if cmdextversion число команда [else if defined переменная команда [else
команда [else выражение] выражение]
выражение]
где: not — и н в е р т и р о в а н и е з а д а н н о г о у с л о в и я ; errorlevel
число —
проверка
кода
в о з в р а т а п р е д ы д у щ е й про-
г р а м м ы . True — е с л и э т о т к о д н е м е н ь ш е з а д а н н о г о ч и с л а ; строка1=-строка2 — с р а в н е н и е д в у х с т р о к ,
п р и э т о м строки
в к а в ы ч к и б р а т ь н е н а д о . В к а ч е с т в е с т р о к м о ж н о з а д а в а т ь знач е н и е п а р а м е т р о в ( % 0 - % 9 ) и л и з н а ч е н и е п е р е м е н н ы х окружения (%Переменная
%);
exist имя
файла — п р о в е р к а с у щ е с т в о в а н и я ф а й л а — исполь-
зовалась выше; оп_сравнения
—
3-буквенная
операция
сравнения.
В каче-
с т в е о п е р а ц и й с р а в н е н и я и с п о л ь з у ю т с я с л е д у ю щ и е операцииEQU ==, NEQ / = , L S S — <, LEQ <=,
GTR>,
GEQ >= .
И — к л ю ч о з н а ч а е т , ч т о п р и с р а в н е н и и с т р о к р е г и с т р н е учит ы в а е т с я , т . е . м а л е н ь к и е и з а г л а в н ы е б у к в ы н е р а з л и ч а ю т с я . Этот к л ю ч т а к ж е м о ж е т б ы т ь и с п о л ь з о в а н в ф о р м е строка1=-строка2 к о м а н д ы if.
Е с л и и строка1,
преобразовываются в числа,
и строка2 с о с т о я т из ц и ф р , строки и в ы п о л н я е т с я с р а в н е н и е чисел.
В этом случае незначащие н у л и не учитываются; cmdextversion
число
—
производит
с р а в н е н и е з а д а н н о г о чис-
л а с в е р с и е й п р о г р а м м ы C m d . e x e . У с л о в и е с cmdextversion н е вып о л н я е т с я , е с л и р а с ш и р е н и я к о м а н д н о г о п р о ц е с с о р а запрещены; defined
переменная
менных среды.
True
—
Дополнительно можно %errorlevel%,
используется
для
проверки
пере-
— е с л и з а д а н н а я п е р е м е н н а я определена. использовать
%cmdcmdline%
и
следующие
%cmdextversion%.
переменные.
Первая
перемев-
н а я з а м е н я е т с я с т р о к о в ы м п р е д с т а в л е н и е м к о д а в о з в р а т а , втор а я — к о м а н д н о й с т р о к о й , з а д а н н о й д л я в ы п о л н е н и я Cmd.exe. е с л и с р е д и п е р е м е н н ы х с р е д ы е щ е н е б ы л о т а к о й переменной, а т р е т ь я — с т р о к о в о е п р е д с т а в л е н и е т е к у щ е г о з н а ч е н и я версии Cmd.exe. выражение
— с о с т о и т из
команды
с
п а р а м е т р а м и , допусти-
м ы м и в з а д а н н о й ОС. Пример. Команда
Результат
echo
WIN
echo echo echo
%OS% %errorlevel% %cmdcmdline% %cmdextversion%
DOWSNT
0
"C:\WINNT\System32\cmd.exe" 2 412
Команда FOR В данном п о с о б и и р а с с м а т р и в а ю т с я т о л ь к о н е к о т о р ы е и з в а риантов и с п о л ь з о в а н и я к о м а н д э т о г о т и п а . П о л н у ю и н ф о р м а ц и ю в о команде f o r м о ж н о п о л у ч и т ь , и с п о л ь з у я п о м о щ ь п о т е к у щ е й мрсии ОС W I N D O W S . Запуск н е к о т о р о й к о м а н д ы д л я к а ж д о г о ф а й л а и з з а д а н н о г о кножества. Команда for м о ж е т б ы т ь и с п о л ь з о в а н а в п а к е т н о й п р о г р а м м е или непосредственно из к о м а н д н о й с т р о к и . В пакетных ф а й л а х и с п о л ь з у е т с я с л е д у ю щ а я ф о р м а к о м а н да for: for %%переменная in (множество) do команда [параметры_команды] Для и с п о л ь з о в а н и я for и з к о м а н д н о й с т р о к и и с п о л ь з у е т с я следующая ф о р м а к о м а н д ы : кгУопеременная
in
(множество)
do
команда
[параметры_команды]
Параметры: %%переменная При
или
выполнении
%переменная команды
%%переменная
(или
%перемен-
нзя) в поле к о м а н д ы з а м е н я е т с я п о с л е д о в а т е л ь н о в с е м и з н а ч е виями, з а д а н н ы м и в з а д а н н о м м н о ж е с т в е . П р и к а ж д о м н о в о м значении п е р е м е н н о й в ы п о л н я е т с я к о м а н д а . З а м е н а в ы п о л н я е т с я с учетом регистра в с е х
символов.
%%переменная
если команда for в к о м а н д н о м ф а й л е .
используется,
%переменная и с п о л ь з у е т с я ,
если переменная в к о м а н д н о й с т р о к е . (множество) Задает о д и н и л и б о л е е ф а й л о в и л и т е к с т о в ы х с т р о к , п о д л е жащих обработке з а д а н н о й к о м а н д о й . С к о б к и я в л я ю т с я о б я з а тельными. команда Задает к о м а н д у , к о т о р а я б у д е т в ы п о л н е н а д л я к а ж д о г о ф а й ла(текстовой с т р о к и ) и з м н о ж е с т в а . параметры_команды Задает п а р а м е т р ы и к л ю ч и д л я в ы з ы в а е м о й к о м а н д ы . Пример. В ы п о л н и т ь т р а н с л я ц и ю с л е д у ю щ и х ф а й л о в с а с с е м блер-программами a . a s m , b . a s m , с . a s m 1 . for%%fin (a.asm b.asm c.asm) do c:\tasm\bin\tasm32 /ml /zi %%f
1 Если заданная команда задается не в командном файле, а в командной строке, •сеременная %%f заменяется переменной %f в обоих случаях.
413
Если используется оператор вида for /D [%% | %]переменная in (множество) do команда [параметры_команды] и в м н о ж е с т в е з а д а н ы и м е н а с о з н а к а м и ( * и ? ) , т о о н и указываются для задания имен каталогов, а не имен файлов. Пример. По команде for/D %f in (*.*) do dir %f б у д е т в ы п о л н е н а к о м а н д а dir д л я в с е х к а т а л о г о в т е к у щ е г о каталога. Д л я р е к у р с и в н о г о п о и с к а в о в с е х в л о ж е н н ы х к а т а л о г а х используется команда вида: да
for/R [[диск :]путь] [%% [параметры_команды]
\ %]переменная in (множество) do коман-
П р о х о д и т по д е р е в у к а т а л о г о в с к о р н е м в [диск:]путь, вып о л н я я и н с т р у к ц и ю for д л я к а ж д о г о к а т а л о г а в д е р е в е . Если пос л е к л ю ч а / R н е з а д а н к а т а л о г , п р е д п о л а г а е т с я т е к у щ и й каталог. Е с л и множество з а д а н о о д н о й т о ч к о й (.), т о к о м а н д а п р о с т о перечислит каталоги в дереве. Пример. О т т р а н с л и р о в а т ь в с е ф а й л ы т и п а . a s m т е к у щ е г о каталога: for/R c:\users\sergey
%%fin
(*.asm)
do
tasm32 /ml/zi
%%f
Циклы с неизвестным числом повторений. К о м а н д а SHIFT И с п о л ь з у е т с я д л я в ы п о л н е н и я к о м а н д н ы х ф а й л о в с перем е н н ы м ч и с л о м п а р а м е т р о в , п р и ч е м к о л и ч е с т в о п а р а м е т р о м мож е т б ы т ь б о л ь ш е 1 0 ( н а п о м и н а е м , ч т о в о б щ е м с л у ч а е параметры о б о з н а ч а ю т с я %0..%9,
и и х к о л и ч е с т в о н е д о л ж н о превосходить
1 0 ) . О б щ и й в и д к о м а н д ы shift / л , к о т о р ы й у к а з ы в а е т к о м а н д е нач и н а т ь с д в и г с n-то а р г у м е н т а , г д е п — ч и с л о от н у л я до восьми. Например, SHIFT/2 с д в и н е т %3 на %2, %4 на %3 и т. д. %0 и %1 о с т а н у т с я неизменными. П р и м е р к о м а н д н о г о ф а й л а д л я к о п и р о в а н и я произвольного числа файлов в заданный каталог. echo off rem MYCOPY.BATКопирование в заданный каталог 414
любого
числа
файлов
rem Синтаксис команды rem MYCOPY dir filel file2 ... :forccpy if "%2"=="" goto break
copy %2 %1/%2 Shift/2 goto forcopy break Рассмотренные в ы ш е с р е д с т в а н а п и с а н и я к о м а н д н ы х ф а й I в показывают, ч т о г р а м о т н о е и с п о л ь з о в а н и е з т и х с р е д с т в з а шую позволяет н е п и с а т ь п р о г р а м м д л я р е а л и з а ц и и п о в т о р я ю т с я действий, а р е а л и з о в а т ь п о с л е д о в а т е л ь н о с т ь н е о б х о д и м ы х действийспомощьюк о м а н д н ы хф а й л о в .
Ю.4. Выполнение сценариев Языки д л я с о з д а н и я с ц е н а р и е в о т н о с я т с я к к л а с с у и н т е р претируемых я з ы к о в , т . е . я з ы к о в , д л я к о т о р ы х к а ж д ы й о п е р а т о р юсле трансляции с р а з у в ы п о л н я е т с я . В э т о м с л у ч а е о ч е р е д н о й ператор м о ж е т з а в и с е т ь о т р е а к ц и и с и с т е м ы н а п р е д ы д у щ и й оператор. Это п о з в о л я е т п о л ь з о в а т е л ю о п е р а т и в н о в з а и м о д е й с т в о вать с ОС. П р о г р а м м ы , п р е д н а з н а ч е н н ы е д л я о б р а б о т к и к о н струкций к о м а н д н ы х я з ы к о в ,
называются командными интер-
претаторами. В ы ш е б ы л р а с с м о т р е н к о м а н д н ы й и н т е р п р е т а т о р WINDOWS, и з в е с т н о с е м е й с т в о к о м а н д н ы х и н т е р п р е т а т о р о в д л я Хкласса U N I X S h e l l .
Ю.4.1. Общая х а р а к т е р и с т и к а командных языков Все к о м а н д ы м о ж н о р а з д е л и т ь н а 3 к л а с с а :
внутренние,
нешнпе к о м а н д ы и к о м а н д н ы е ф а й л ы . В н у т р е н н и е к о м а н д ы и н 1
:е[шретатора в с т р о е н ы в с а м и н т е р п р е т а т о р ( н а п р и м е р , к о м а н д а ID). Внешние к о м а н д ы — э т о п р о г р а м м ы , к о т о р ы е з а п у с к а ю т с я н и выполнении н е к о т о р ы х к о м а н д ( н а п р и м е р , FC). И м е н а э т и х 1 «грамм с о в п а д а ю т с и м е н а м и к о м а н д ы . П р и з а п у с к е к о м а н д
второго типа с о з д а е т с я п р о ц е с с , в к о т о р о м з а п у с к а е т с я с о о т в е т о т ю щ а я программа. К о м а н д н ы е ф а й л ы состоят и з в н у т р е н н и х , вешних к о м а н д и ( и л и ) д р у г и х к о м а н д н ы х ф а й л о в . Важной о с о б е н н о с т ь ю к о м а н д н ы х я з ы к о в я в л я е т с я в о з м о ж ность п е р е н а п р а в л е н и я р е з у л ь т а т о в в в о д а и в ы в о д а и н ф о р м а ц и и .
415
Перенаправление вывода мы использовали, с п и с о к к о м а н д W I N D O W S ( о п е р а т о р HELP
к о г д а определяли >
Имя
файла). Оно
п о з в о л я е т в ы в о д и т ь р е з у л ь т а т ы р а б о т ы п р о г р а м м ы в ф а й л , заданный после знака >. К о м а н д н ы й и н т е р п р е т а т о р р а б о т а е т с п е р е м е н н ы м и окружен и я . Э т и п е р е м е н н ы е м о ж н о р а з б и т ь н а 2 к л а с с а . К п е р в о м у клас с у о т н о с я т с я п е р е м е н н ы е о к р у ж е н и я , з н а ч е н и я к о т о р ы х могут и с п о л ь з о в а т ь в с е п р и л о ж е н и я ( о б щ и е п е р е м е н н ы е окружения). К о в т о р о м у к л а с с у о т н о с я т с я п е р е м е н н ы е о к р у ж е н и я , которые у с т а н о в л е н ы п р и л о ж е н и е м , з н а ч е н и я э т и х п е р е м е н н ы х теряются п р и з а в е р ш е н и и п р и л о ж е н и я . Л ю б о й п о л ь з о в а т е л ь м о ж е т доб а в и т ь , и з м е н и т ь и л и у д а л и т ь п е р е м е н н у ю с р е д ы второго класса (сл.
функцию
SetEnvironment).
Однако
системную
переменную
п е р в о г о т и п а м о ж е т д о б а в и т ь , и з м е н и т ь и л и у д а л и т ь т о л ь к о администратор. Р а с с м о т р и м о с н о в н ы е п е р е м е н н ы е п е р в о г о к л а с с а для ОС W I N D O W S . Д л я п р о с м о т р а з н а ч е н и й п е р е м е н н ы х э т о г о класса н е о б х о д и м о п е р е й т и на П е р е м е н н ы е среды (Пуск->Настройка~* Панель
управления—>Система^Дополнительно->Переменные
среды). Э т и п е р е м е н н ы е д е л я т с я н а 2 г р у п п ы : п е р е м е н н ы е среды дчя заданного пользователя и системные переменные. П е р е м е н н ы е с р е д ы п о л ь з о в а т е л я м о г у т б ы т ь различными д л я к а ж д о г о п о л ь з о в а т е л я о т д е л ь н о г о к о м п ь ю т е р а , включают в с е б я : в с е п е р е м е н н ы е , у с т а н о в л е н н ы е д а н н ы м пользователем; п е р е м е н н ы е , о п р е д е л е н н ы е п р и л о ж е н и я м и ; п у т и к п а п к а м , где н а х о д я т с я ф а й л ы п р и л о ж е н и й , н а п р и м е р include, lib, path. С и с т е м н ы е п е р е м е н н ы е я в л я ю т с я о б щ и м и д л я в с е х пользователей.
Рассмотрим
CESSORS,
OS,
Path,
примеры таких
констант.
PROCESSOR_ARCHITECTURE,
NUMBER_OFPROwindir
Таким
о б р а з о м , в м е с т о о п р е д е л е н и я п а р а м е т р о в п р о ц е с с о р о в и текущей ОС м о ж н о п р о с т о о б р а т и т ь с я к с о о т в е т с т в у ю щ и м переменным среды. Притер. П р о ч е с т ь з н а ч е н и е п е р е м е н н о й с р е д ы OS: ttinclude <windows.h> ttinclude <stdio.h> int main(int argc, char* argv[])
{
char Buffer[256]; DWORD dwSize =
GetEnvironmentVariable( 416
"OS",
Buffer, sizeof (Buffer)
);
)
printf("%s\n", getchar (); return 0;
Buffer);
Для W I N D O W S 2 0 0 0 п р о г р а м м а в о з в р а щ а е т W I N D O W S _ N T . В командном ф а й л е п е р е м е н н а я с р е д ы з а к л ю ч а е т с я в с и м галы %, н а п р и м е р , к о м а н д н ы й ф а й л , с о д е р ж а щ и й с т р о к у ECHO 0S%, выведет з н а ч е н и е п е р е м е н н о й с р е д ы W I N D O W S _ N T . Два варианта п р и м е р а в ы в о д а у с т а н о в л е н н о й О С п о к а з ы в а ют, что одну и ту же з а д а ч у м о ж н о р е ш и т ь с п о м о щ ь ю п р о г р а м м ы ш командного ф а й л а . О ч е в и д н о , ч т о в т о р о й в а р и а н т р е ш е н и я шее простой и н е т р е б у е т д о п о л н и т е л ь н ы х ш а г о в , т а к и х к а к ишпиляция и к о м п о н о в к а п р о г р а м м ы , б о л е е т о г о , о н в о о б щ е н е гребует наличия п р о г р а м м н о й с р е д ы д л я р а з р а б о т к и п р о г р а м м . Класс задач, к о т о р ы е м о ж н о р е ш и т ь с п о м о щ ь ю в т о р о г о в а р и а н т а , иачительно р а с ш и р я е т с я п р и у с о в е р ш е н с т в о в а н и и я з ы к а з а д а шякоманд. Н и ж е р а с с м о т р е н ы в о з м о ж н о с т и п о р а с п а р а л л е л и в а вию задач для м н о г о п р о ц е с с о р н ы х с и с т е м .
10.4.2. Командные файлы и п а р а л л е л ь н о е выполнение программ Язык н а п и с а н и я к о м а н д н ы х ф а й л о в д л я О С к л а с с а U N I X (Интерпретатор shelf) п о з в о л я ю т з а д а т ь р е ж и м п а р а л л е л ь н о г о в ы мнения п р и л о ж е н и й . I
Несколько к о м а н д , р а з д е л е н н ы х с и м в о л о м « | » , н а з ы в а ю т -
с я конвейером. П р и в ы п о л н е н и и к о н в е й е р а с т а н д а р т н ы й в ы в о д к д о й команды к о н в е й е р а , к р о м е п о с л е д н е й , н а п р а в л я е т с я н а «таядартный в х о д с л е д у ю щ е й к о м а н д ы . И н т е р п р е т а т о р shell о ж и •ет завершения п о с л е д н е й к о м а н д ы к о н в е й е р а . К о д з а в е р ш е н и я пиедней к о м а н д ы с ч и т а е т с я к о д о м з а в е р ш е н и я в с е г о к о н в е й е р а . Можно с о е д и н и т ь н е с к о л ь к о к о н в е й е р о в с и м в о л а м и
«;»,
tS», *<5<£», «||». В к о н ц е п о с л е д о в а т е л ь н о с т и к о н в е й е р о в , м о ж н о «пользовать о д и н и з з н а к о в «;» и л и «<&». Р а з д е л и т е л ь м е ж д у к о н ейерами «;» о з н а ч а е т , ч т о т р е б у е т с я п о с л е д о в а т е л ь н о е в ы п о л н е теконвейеров; <<&» о з н а ч а е т , ч т о к о н в е й е р ы м о г у т в ы п о л н я т ь с я
417
п а р а л л е л ь н о . И с п о л ь з о в а н и е в к а ч е с т в е р а з д е л и т е л я символов «<&<£» ( и «||») о з н а ч а е т , ч т о с л е д у ю щ и й к о н в е й е р б у д е т выполнятьс я т о л ь к о в т о м с л у ч а е , е с л и п р е д ы д у щ и й к о н в е й е р завершился с к о д о м з а в е р ш е н и я «О» ( т . е . н о р м а л ь н о ) . П р и о р г а н и з а ц и и спис к а с и м в о л ы «;» и «&» и м е ю т о д и н а к о в ы е п р и о р и т е т ы , меньшие, ч е м у р а з д е л и т е л е й «&&» и <<||».
10.5. Влияние языков сценариев на программирование П р и с о з д а н и и п р и л о ж е н и я о б ы ч н о и с п о л ь з у е т с я какая-го среда разработки, например,
V i s u a l S t u d i o , С + + B u i l d e r или
д р у г и е . О ч е н ь ч а с т о д л я с о в р е м е н н ы х п р и л о ж е н и й д о л ж н а быть р е ш е н а п р о б л е м а и н т е г р а ц и и в п р и л о ж е н и и к о м п о н е н т о в , созданн ы х с п о м о щ ь ю р а з л и ч н ы х с р е д . И н т е г р а ц и я и м е ю щ и х с я ресурс о в п о з в о л я е т з н а ч и т е л ь н о б ы с т р е е р а з р а б о т а т ь н е о б х о д и м о е ПО. И н ф р а с т р у к т у р а и н ф о р м а ц и о н н ы х т е х н о л о г и й д л я соврем е н н о г о п р е д п р и я т и я с о с т о и т и з м н о ж е с т в а п р и л о ж е н и й , устр о й с т в , п р о т о к о л о в , и с т о ч н и к о в д а н н ы х и о б о л о ч е к . Ч т о б ы предп р и я т и е м о г л о р а б о т а т ь э ф ф е к т и в н о , в с е э т и р е с у р с ы необходимо к о о р д и н и р о в а т ь , к р о м е т о г о , д о л ж е н с у щ е с т в о в а т ь способ, поз в о л я ю щ и й л е г к о с о з д а в а т ь н о в ы е п р и л о ж е н и я , с п о с о б н ы е н а нов о м у р о в н е и с п о л ь з о в а т ь в о з м о ж н о с т и с у щ е с т в у ю щ и х ресурсов. Д о л ж н а б ы т ь п р е д о с т а в л е н а в о з м о ж н о с т ь и н т е г р а ц и и существующ и х систем с вновь разрабатываемыми. Д л я р е ш е н и я э т и х п р о б л е м м о ж н о и с п о л ь з о в а т ь я з ы к и программирования, Вспомните, используя
н о э т о р е ш е н и е я в л я е т с я о ч е н ь громоздким.
к а к в ы з в а т ь п р и л о ж е н и е и з д р у г о г о приложения, язык программирования (функция
CreatePocess, на-
п р и м е р ) , к о м п и л я ц и ю и к о м п о н о в к у п р и л о ж е н и я , возможности п о и с п о л ь з о в а н и ю д а н н ы х , с ф о р м и р о в а н н ы х д р у г и м приложен и е м . С р а в н и т е э т о т с п о с о б с и с п о л ь з о в а н и е м к о м а н д н о г о языка, в к о т о р о м д о с т а т о ч н о н а п и с а т ь и м я п р и л о ж е н и я и е г о параметры. П о э т о м у б о л е е п е р с п е к т и в н ы м и д л я р е ш е н и я з а д а ч интеграции являются языки сценариев. С е г о д н я р а з р а б а т ы в а ю т с я я з ы к и с ц е н а р и е в с п е ц и а л ь н о для и с п о л ь з о в а н и я н а у р о в н е п р е д п р и я т и я . П р и м е р о м т а к о г о языка я в л я е т с я я з ы к T e l . Р а с с м о т р е н и е т а к и х я з ы к о в в ы х о д и т з а рамки данного учебного пособия.
418
10.6. Вопросы и задачи 1. Приведите п р и м е р ы , к о г д а и с п о л ь з о в а н и е к о м а н д н ы х ф а й л о в оправдано. 2. Каким о б р а з о м п о л у ч и т ь с п и с о к всех к о м а н д , к о т о р ы е м о ж н о использовать в к о м а н д н ы х ф а й л а х о п е р а ц и о н н о й с и с т е м ы , к о т о рую вы п р и м е н я е т е ? 3. Как м о ж н о у ч е с т ь к о д возврата п р о г р а м м ы в к о м а н д н о м ф а й л е ? 4. Какое з н а ч е н и е с л е д у е т в о з в р а щ а т ь п р и н о р м а л ь н о м и о ш и б о ч ном з а в е р ш е н и я х п р о г р а м м ы ? 5. Составьте к о м а н д н ы й ф а й л , к о т о р ы й : в ы з ы в а е т т е к с т о в ы й редактор д л я с о з д а н и я з а д а н н ы х ф а й л о в , в ы з ы в а е т а р х и в а т о р д л я архивирования с о з д а н н ы х ф а й л о в , в ы з ы в а е т п р о г р а м м у п о ч т о вого к л и е н т а д л я о т п р а в к и с о з д а н н о г о а р х и в а . С р а в н и т е в р е м я создания т а к о г о ф а й л а с о в р е м е н е м , н е о б х о д и м ы м н а с о з д а н и е программы с т а к и м и же ф у н к ц и я м и (см. 4 . 4 . 1 ) .
419
11. СТРУКТУРНАЯ О Б Р А Б О Т К А И С К Л Ю Ч Е Н И Й
Цели изучения раздела: 1. Изучить средство обработки завершения функции 2- Научиться использовать средства обработки исключений, включенные в трансляторы. 3- Исследовать возможность использования структурной обрабопи исключений в динамических библиотеках.
П р и н а п и с а н и и п р о г р а м м ы б о л ь ш а я ч а с т ь к о д а необходима д л я п р о в е р к и п р а в и л ь н о с т и з а д а н и я и с х о д н ы х и промежуточных д а н н ы х - Н а п р и м е р , п р о в е р я е т с я , н а х о д я т с я л и д а н н ы е в требуе м о м д и а п а з о н е , н е р а в н ы л и н у л ю у к а з а т е л и и л и делитель, н е в ы ч и с л я е т с я л и л о г а р и ф м о т р и ц а т е л ь н о г о ч и с л а и д р . Е с л и таких п р о в е р о к н е д е л а т ь , э т о м о ж е т п р и в е с т и к н е б л а г о п о л у ч н о м у зав е р ш е н и ю п р о г р а м м ы б е з и д е н т и ф и к а ц и и м е с т а о ш и б к и и е е ори ч и н ы . Э т о в а ж н о д л я л ю б о й п р о г р а м м ы и н е о б х о д и м о д л я системн ы х п р о г р а м м . С р е д с т в а о б р а б о т к и и с к л ю ч е н и й предназначен! для автоматизации данной обработки. С р е д с т в а о б р а б о т к и и с к л ю ч е н и й м о ж н о р а з д е л и т ь н а два класса: средства обработки, в к л ю ч е н н ы е в я з ы к Cf f tfry..catch). и с р е д с т в а о б р а б о т к и , в к л ю ч е н н ы е в к о м п и л я т о р ы , например, д л я Visual Studio ( try.. finally, try.. except). С р е д с т в а обраб о т к и и с к л ю ч е н и й , в к л ю ч е н н ы е в я з ы к С + + {try..catch), рлссма т р и в а ю т с я в к у р с а х п р о г р а м м и р о в а н и я на С + + и в д а н н о м пособии не рассматриваются. Р а с с м о т р и м средства обработки и с к л ю ч е н и й , включевные в т р а н с л я т о р ы . З а м е т и м , ч т о р а з р а б о т ч и к и т р а н с л я т о р а заботятся о преемственности кода, так б л о к и try.. finally, try. except п о д д е р ж и в а ю т с я н е т о л ь к о в V i s u a l S t u d i o , н о и в С + + Builder. 370
Ксожалению, к о д , к о т о р ы й ф о р м и р у е т с я о б о и м и т р а н с л я т о р а м и , н е вполне с о в м е с т и м . Т а к , п р и и с п о л ь з о в а н и и D L L , с о д е р ж а щ е й средства о б р а б о т к и и с к л ю ч е н и й , р а з р а б о т а н н о й в о д н о й с р е д е , могут в о з н и к н у т ь п р о б л е м ы в д р у г о й с р е д е . К р о м е т о г о , т р а н с лятор в с т а в л я е т д о п о л н и т е л ь н ы й к о д д л я п е р е х о д а н а т р е б у е м ы й блок, если э т о т п е р е х о д д о л ж е н б ы т ь в ы п о л н е н , ч т о у м е н ь ш а е т , иногда з н а ч и т е л ь н о , э ф ф е к т и в н о с т ь к о д а . П о э т о м у с р е д с т в а о б работки и с к л ю ч е н и й м о ж н о и с п о л ь з о в а т ь , е с л и п р и л о ж е н и е п о л ностью п и ш е т с я в о д н о й с р е д е . И н е п р е д ъ я в л я е т с я ж е с т к и х требований к р е с у р с а м . Д а л е е р а с с м о т р е н ы с р е д с т в а о б р а б о т к и исключений д л я V i s u a l S t u d i o . Н а и б о л е е п о л н о д а н н ы й в о п р о с рассмотрен в [ 3 ] .
11.1. Обработка завершения Очень ч а с т о к о д п р о г р а м м ы с о д е р ж и т м н о г о у ч а с т к о в п р о граммы вида:
if (...){Вывод сообщения об ошибке; return;} В этом с л у ч а е к о д п о л у ч и т с я д л я р а з р а б о т ч и к а б о л е е п р о стым, е с л и и с п о л ь з о в а т ь о б р а б о т к у з а в е р ш е н и я . А н а л о г и ч н о использованию t r y о п р е д е л я е т с я з а щ и щ е н н ы й б л о к с п о м о щ ь ю f r y . Если н е о б х о д и м о о п р е д е л и т ь к о д , к о т о р ы й н а д о в ы п о л н и т ь при завершении ф у н к ц и и , и с п о л ь з у е т с я б л о к __finally. Э т о т б л о к выполняется п р и л ю б ы х с п о с о б а х з а в е р ш е н и я ф у н к ц и и ( с п о м о щью return, exit, goto). С т р у к т у р а п р о г р а м м ы с б л о к о м з а в е р ш е ния
1гу{ II Защищаемый блок
}
finally{ 1/Блок завершения
} Блок з а в е р ш е н и я в ы п о л н я е т с я , е с л и в з а щ и щ е н н о м б л о к е выполняется в ы х о д в с л у ч а е н о р м а л ь н о г о з а в е р ш е н и я э т о г о б л о к а или в случае п р е ж д е в р е м е н н о г о в ы х о д а и з н е г о . Р а с с м о т р и м п р и мер функции к о п и р о в а н и я ф а й л а , р е а л и з о в а н н о й б е з и с п о л ь з о в а ния и с и с п о л ь з о в а н и е м б л о к а з а в е р ш е н и я .
421
/I Функция копирования без использования блока завершения «include "stdafx.h" Umclude <wmdows h> #include <stdio.h> 370 ttusing <mscorfib.dll> using namespace System; enum ERRORS ( COPYFILE_ OK. COPYFILEOPENSRCFILE. COPYFILE OPENDESTFILE. COPYFILE_NOMEMORY. OPYFILE_ READFILE. COPYFILE_WRITEFILE ): int CopyFile (const char ' src. const char' dest) { HANDLE hSrc = CreateFile ( src„ GENERIC_READ. FILE_SHARE_READ. 0. OPEN_EXISTING. 0. 0); if(hSrc ~~ INVALID_HANDLE_VALUE) return COPYHLE_OPENSRCFILE; HANOLE hDest = CreateFile ( ~dest".GENERIC_WRlTE,FtLESHARE_READ.O,CREATE_ALWAYS 0. 0) : if (hDest == INVALID HANDLE^ VALUE){ CloseHandle (hSrc): return COPYFILEOPENDESTFILE. J DWORD dwSize ~ GetFiteSize (hSrc, 0): BYTE'pMem = new BYTE{dwSizeJ. if(pMem ==0){ CloseHandle (hSrc); CloseHandle (hDest). return COPYFILE_NOMEMORY:
}
DWORD dwCount: BOOL b = ReadFile (hSrc. pMem. dwSize &dwCount. 0): * (ty {
>
CloseHandle (hSrc); CloseHandle (hDest); delete[]pMem; return COPYFILE_READFILE;
b = WriteFile (hDest. pMem, dwSize. &dwCounl. 0); if Ob) { CloseHandle (hSrc); CloseHandle (hDest);
delete[]pMem; return COPYFILE_ WRITEFILE;
}
}
CloseHandle (hSrc); CloseHandle (hDest); delete[]pMem; return COPYFILE_OK;
int_tmain() I int res = CopyFile ("c.WtmpWException.txt", "с: 11 tmp 11 Exception.bak"); switch (res) { case COPYFILE_OK: printf СCOPYFILE_OK\n"); break; case COPYFILE_OPENSRCFILE: printf CCOPYFILE_OPENSRCFILE\n"); break; case COPYFILE_OPENDESTFILE: printf ("COPYFILE_OPENDESTFILE\n"); break; case COPYFILE_NOMEMORY: printf ("COPYFILE_NOMEMORY\n");break; case COPYFILE_ REA DFILE: printf ("COPYFILE_READFILE\n");break; case С OPYFILE_ WRITEFILE: printf ("COPYFILE_WRITEFILE\n");break; } return 0;
} Обратите в н и м а н и е , ч т о в ф у н к ц и и н е о б х о д и м о з а к р ы в а т ь открытые ф а й л ы и о с в о б о ж д а т ь п а м я т ь к а ж д ы й р а з п р и н е б л а г о получном з а в е р ш е н и и ф у н к ц и и . Эта ж е ф у н к ц и я с б л о к о м з а в е р ш е н и я .
int CopyFile (const char * src, const char* dest) { int res = COPYFILE_OK; HANDLE hSrc = INVALID_HANDLE_ VALUE; HANDLE hDest = IN VA L ID_ HA NDL E_ VA L UE; PBYTEpMem = 0; try
{ hSrc = CreateFile (src, GENERIC_READ, FILE_SHARE_READ, 0, OPEN EXISTING, FILE_ATTRIBUTE_ NORMAL, 0); if (hSrc == INVALID HANDLE_VALUE) return res = COPYFILE_OPENSRCFILE; hDest = CreateFile ("dest", GENE RIC_ WRI ТЕ, FILE_ SHA RE_ READ, 0, CREATE_ALWAYS, 0, 0); 423
if (hDest == INVALIDHANDLEVALUE) return res = COPYFILE_OPENDESTFILE; DWORO dwSize = GetFileSize (hSrc. 0); pMem = new BYTE]dwSize/; iffpMem == Ofreturn res = COPYFILE NOMEMORY DWORD dwCount: BOOL b = ReadFile (hSrc. pMem. dwSize. SdnCounl 0), if(fb)return res = COP YFILE_ READFILE; b = WriteFile (hDest. pMem. dwSize. &dwCount 0) if (lb) return res = COPYFILE WRITEFILE:
}
finally
{ if (hSrc .'= INVALID HANDLE VALUE)OoseHanBe (hSrc); if (hDest 1= INVALID_ HANDLE_VALUE)C1oseHarKlte (hDest): if(pMem) deleteflpMem.
)
return res;
} С р а в н и т е обе ф у н к ц и и ! О ч е в и д н о , ч т о в т о р о й вариант кор о ч е , н а г л я д н е е и у м е н ь ш е н а в е р о я т н о с т ь «забыть* освободить в ы д е л е н н ы й ресурс п р и н е б л а г о п о л у ч н о м з а в е р ш е н и я функция, что м о ж е т привести к б о л ь ш и м н е п р и я т н о с т я м п р и многократном в ы з о в е этой ф у н к ц и и . Р а с с м о т р и м а л г о р и т м в ы п о л н е н и я п р о г р а м м ы с блоком завершения. Б л о к з я в с р ш е н и я в ы п о л н я е т с я , е с л и прогрпмма выполняет е с т е с т в е н н ы й п е р е х о д на н е г о ( з а в е р ш е н к о н т р о л и р у е м ы й блок) и л и в к о н т р о л и р у е м о м б л о к е о б н а р у ж е н а к о м а н д а перехода за пределы этого б л о к а ( к о м а н д ы return, goto, continue, break). После в ы п о л н е н и я б л о к а з а в е р ш е н и я м о г у т в ы п о л н я т ь с я различные операторы в з а в и с и м о с т и от того, по к а к о й п р и ч и н е мы попали на б л о к з а в е р ш е н и я . Е с л и п е р е х о д в а д а н н ы й б л о к в ы п о л н е н п р и естественной в ы п о л н е н и и , то после в ы п о л н е н и я этого блока в ы п о л н я ю т с я операторы, следующие за блоком завершения. Е с л и п е р е х о д на э т о т б л о к в ы п о л н е н по оператору return, т о п о с л е в ы п о л н е н и я б л о к а з а в е р ш е н и я в ы п о л н я е т с я оператор return, н е з а в и с и м о от того, к а к и е о п е р а т о р ы н а х о д я т с я между блоком з а в е р ш е н и я и оператором return. 370
Если п е р е х о д н а э т о т б л о к в ы п о л н е н п о о п е р а т о р у continue, т о после в ы п о л н е н и я б л о к а з а в е р ш е н и я в ы п о л н я е т с я п е р е х о д н а заголовок ц и к л а , а е с л и п о о п е р а т о р у break, т о п о с л е в ы п о л н е н и я блока з а в е р ш е н и я в ы п о л н я е т с я о п е р а т о р п о с л е ц и к л а . Еще р а з н а п о м и н а е м , ч т о и с п о л ь з о в а н и е б л о к а з а в е р ш е н и я ножет у в е л и ч и т ь в р е м я в ы п о л н е н и я ф у н к ц и и з а с ч е т г е н е р а ц и и транслятором д о п о л н и т е л ь н о г о к о д а д л я п р о в е р к и и р е а л и з а ц и и всех о п и с а н н ы х в ы ш е в а р и а н т о в . Д л я у м е н ь ш е н и я в р е м е н н ы х потерь д л я в ы х о д а и з у п р а в л я ю щ е г о б л о к а м о ж н о и с п о л ь з о в а т ь оператор
leave
в м е с т о о п е р а т о р а return,
который
выполняется
как оператор п е р е х о д а в к о н е ц у п р а в л я ю щ е г о б л о к а . В э т о м с л у чае код з а в е р ш е н и я н у ж н о з а д а т ь з а р а н е е .
11.2. Обработка исключений Напоминаем, что и с к л ю ч е н и е — это н а р у ш е н и е п о р я д к а выполнения о п е р а т о р о в п р о г р а м м ы . Ч а щ е в с е г о и с к л ю ч е н и я с в я з а ны с н е в о з м о ж н о с т ь ю п р о д о л ж е н и я о б ы ч н о г о в ы п о л н е н и я о п е р а торов, н а п р и м е р , в с в я з и с о б р а щ е н и е м к н е д о п у с т и м о м у а д р е с у , делению н а н о л ь и д р . О б р а б о т к о й и с к л ю ч е н и й з а н и м а е т с я ОС. Программа с о б р а б о т ч и к о м и с к л ю ч е н и й и м е е т в и д : try
г
//Защищенный
}
except
блок
(Фильтр
исключений)
1 Обработчик
}
//Продолжение
исключений
программы
Фильтр и с к л ю ч е н и й о п р е д е л я е т , ч т о д е л а т ь п о с л е о б р а б о т к и . Это в ы р а ж е н и е , з н а ч е н и е к о т о р о г о ц е л о е ч и с л о . З н а ч е н и я з т и х констант о п р е д е л е н ы н и ж е : Udefine EXCEPTION_ EXEC U ТЕ HA NDLER #define EXCEPTION_ CONTINUE SEARCH «define EXCEPTION_CONTINUE_EXECUTION 425
1 0 -1
11.2.1. Фильтр EXCEPTION.EXECUTE.HANDLER Фильтр EXCEPTtON_EXECUTE_HANDLER используется. если необходимо после обработчика исключений перейти к коду, который задан после блока с обработчиком исключений. Этот ф и л ь т р используется наиболее часто. Пример. Составить ф у н к ц и ю д л я подсчета количества цифр в строке. int DigitNumbers (const char "str) int Numbers = -1; -Jry for (inl i = 0:slr[i]; i++) if (strfi] >='0" «& strfl <= 'S'> Numbers Numbers++ except (EXCEPTION_EXECUTE_HANDLER)0 return Numbers, В этом примере, если адрес исходной строки равен 0 пли является недопустимым адресом ( ф у н к ц и я вызывается оператором Numbers — DigitNumbers (О);), то при выполнении заголовка цикла произойдет исключение, связанное с обращением к недопустимой памяти, будет вызван обработчик исключений, который в данном случае я в л я е т с я пустым. Т а к к а к ф и л ь т р , заданный в заголовке обработчика, равен EXCEPTlON_EXECUTE_HANDLER, то после выполнения обработчика будет выполнен оператор return Numbers; и ф у н к ц и я возвратит результат р а в н ы й 1. Если строна пустая, то в ц и к л подсчета не входим, и ф у н к ц и я возвращает 0. Если строка не пустая, то входим в ц и к л и считаем количество цифр. В этом случае обработчик исключений пропускается. Если бы обработчик исключений не был задан для функции, то ОС искала бы обработчика исключений в вызызающей функц и и . Если ОС доходит до самого верхнего уровня и не находит обработчика исключений, то используется обработчик ОС. Перед запуском обработчика исключений в ы п о л н я ю т с я блоки finally. если они есть д л я внутренних функций при переходе на очередной уровень в поиске обработчика. Если д л я предыдущего примере к о д обработчика не писать, исключение приведет к прерыванию программы с сообщением, которое зависит от версии ОС. 370
11.2.2.
Фильтр
EXCEPTION_CONTINUE_EXECUTION
Этот ф и л ь т р и с п о л ь з у е т с я п р и н е о б х о д и м о с т и в м е с т о о б р а ботчика и с к л ю ч е н и й с н о в а в ы п о л н и т ь к о м а н д у , к о т о р а я п р и в е л а к исключению. Д л я э т о г о в в ы р а ж е н и и , к о т о р о е з а п и с ы в а е т с я в заголовке б л о к а except, в м е с т о к о н к р е т н о г о з н а ч е н и я к о н с т а н т ы задается в ы з о в ф у н к ц и и , и с п р а в л я ю щ е й т р е б у е м ы е д а н н ы е и возвращающей значение EXCEPTION_CONTINUE_EXECUTION. Например, е с л и в ы п о л н я л о с ь д е л е н и е н а 0 , т о к о м а н д а п р и в е д е т к исключению. Д л я и с п р а в л е н и я к о м а н д ы д о с т а т о ч н о з а д а т ь н о вое значение д е л и т е л я , о т л и ч н о е о т н у л я . В э т о м с л у ч а е п о в т о р н о е | выполнение к о м а н д ы к и с к л ю ч е н и ю у ж е н е п р и в е д е т . В п р о г р а м ме, п р и в е д е н н о й н и ж е , ф у н к ц и я в ы в о д и т с о о б щ е н и е о д е л е н и и на 0 и и с п р а в л я е т з н а ч е н и е д е л и т е л я . З а м е т и м , ч т о т а к о е и с п р а в ление н е в с е г д а п р и в о д и т к к о д у , в к о т о р о м к о м а н д а д е л е н и я п о сле и с п р а в л е н и я в ы п о л н я е т с я в е р н о . Так, н а п р и м е р , к о д : // This is the main project file for VC++ application project //generated using an Application Wizard. ttinclude "stdafx.h" ttinclude <windows.h> ttinclude <stdio.h> ttusing <mscorlib.dll> using namespace System; int Filter (int *a) { MessageBox (0, "ZeroDivide", "Error", 0); *a = 1' return EXCEPTION CONTINUE EXECUTION;
}
int Divide (int x, int y) { intz; char "a; _Jry( z - x/y;
}
except (Filter (&y)) return z;
( }
}
MJmainQ { int z = Divide (5, 0); printf ("z = %d\n", z); return 0;
} 427
В V i s u a l S t u d i o N e t д е л и т е л ь к о м а н д ы не исправляется и иск л ю ч е н и е о с т а е т с я , х о т я п р о с м о т р х о д а в ы п о л н е н и я программы в о т л а д ч и к е свидетельствует о т о м , ч т о з н а ч е н и е донной переменной в п а м я т и и с п р а в л я е т с я . Это м о ж н о о б ъ я с н и т ь т о л ь к о тем, что д е л и т е л ь н а х о д и т с я в к э ш е , а з н а ч е н и е переменной исправляется в п а м я т и . Д л я С + + B u i l d e r и V i s u a l S t u d i o 6 . 0 эта программа выдает о ж и д а е м ы й р е з у л ь т а т р а в н ы м 5 после сообщения о делении в а 0 . 11.2.3. Фильтр EXCEPT/ON_CONT/Nl/E_SEARCH И с к л ю ч е н и е , з а д а н н о е в т е к у щ е м б л о к е , не обрабатывается. Системе н а х о д и т обработчик и с к л ю ч е н и я в очередном блоке, для которого з а д а н н ы й блок я в л я е т с я в л о ж е н н ы м . Е с л и это верхний уровень, то и с к л ю ч е н и е о б р а б а т ы в а е т с я ОС. П р и м е р п р о г р а м м ы , к о г д а есть о б р а б о т ч и к и д л я функции и главной п р о г р а м м ы , и с к л ю ч е н и е , с в я з а н н о е с обращением к нул е в о м у адресу, в о з н и к а е т в ф у н к ц и и , но обрабатывеется это исключение в главной программе. tbnclude "stdafx h" ttinclude <wmdows.h> #include <stdio.h> ttusing <mscorhb.dlt> using namespace System; int StrLen (const char 'str){
mti = -1. <
НУ
for (; sir ]i + 1]; i** ); f++.
) excepf (EXCEPTI ON_CONTINUE_ SEARCH ) (
MessageBox (0. 'except for function'. "Except". 0):
) return i;
I
int _tmain() ( int len =-1:
try {
)ten = StrLen (0): except
(EXCEPTION_EXECUTE_HANDLER)
{ 370
MessageBox (0, "except for main program", "Except", 0);
}
printf ("ten = %d\n", ten); return 0;
} П р о г р а м м а в ы д а с т с о о б щ е н и е except for main program и д л и [y, равную —1. Д л я п у с т о й с т р о к и в ы д а е т с я д л и н а , р а в н а я 0 . Д л я троки с с и м в о л а м и в ы д а е т с я д л и н а , р а в н а я к о л и ч е с т в у с и м в о л о в )ез нулевого з а в е р ш и т е л я . Э т о т в а р и а н т о б р а б о т к и и с п о л ь з у е т с я , ;сли в н у т р е н н и е ф у н к ц и и н е х о т я т и л и н е з н а ю т , к а к о б р а б о т а т ь исключение. Анализ р а с с м о т р е н н ы х м е т о д о в о б р а б о т к и и с к л ю ч е н и й показал, что в с л у ч а е и с п о л ь з о в а н и я э т и х с р е д с т в к о д с т а н о в и т с я б о лее н а д е ж н ы м з а с ч е т у м е н ь ш е н и я в е р о я т н о с т и о ш и б к и . Т а к к а к ошибка о б р а б а т ы в а е т с я в о д н о м м е с т е , в с е г д а м о ж н о о п р е д е л и т ь причину о ш и б к и , а н е к о т о р ы е о ш и б к и д а ж е и с п р а в и т ь . Р а з р а б о т к а надежного к о д а о с о б е н н о в а ж н а , е с л и э т о т к о д я в л я е т с я к о д о м для библиотек. В т о ж е в р е м я н е о б х о д и м о п о м н и т ь о б о п а с н о с т и возможной н е с о в м е с т и м о с т и к о д о в д л я р а з н ы х с р е д р а з р а б о т к и .
11.3. Вопросы и задачи 1. В каком случае выполняется переход в программе на блок Finally? 2. Составьте 3 варианта ф у н к ц и и д л я о б ъ е д и н е н и я д в у х ф а й л о в в один ф а й л п у т е м з а п и с и с н а ч а л а п е р в о г о , а з а т е м второго файлов. В первом варианте не и с п о л ь з у й т е средств о б р а б о т к и исключений вообще. Во втором варианте используйте блоки try., except я з ы к а С + + , в третьем варианте — блок з а в е р ш е н и я . Проанализируйте р а з м е р ф у н к ц и и д л я к а ж д о г о варианта и время выполнения всех т р е х вариантов ф у н к ц и й . Сделайте выводы об эффективности э т и х средств с т о ч к и з р е н и я в ы ч и с л и т е л ь н о й сложности. 3. Проанализируйте ассемблерный код д л я к а ж д о г о варианта функции в р а з л и ч н ы х с р е д а х ( С + + Builder, V i s u a l S t u d i o 6, Visual Studio 7, н а п р и м е р ) . Сделайте п р е д п о л о ж е н и е о в о з м о ж н о сти совместного и с п о л ь з о в а н и я кодов. 4. Проверьте п р е д п о л о ж е н и е о в о з м о ж н о с т и и с п о л ь з о в а н и я з а щ и щенных блоков с f i n a l l y в р а з л и ч н ы х с р е д а х . Д л я этого предыдущую ф у н к ц и ю для последнего варианта включите в DLL. Используйте э т у ф у н к ц и ю в р а з л и ч н ы х с р е д а х ( С + + B u i l d e r , Visual S t u d i o 6, V i s u a l S t u d i o 7, например). Сделайте вывод о совместимости кода д л я р а з л и ч н ы х сред. В к а к о м с л у ч а е возможны о ш и б к и ? 5. Составьте п р и м е р с д е л е н и е м на 0. Проверьте в о з м о ж н о с т ь исправления д е л и т е л я д л я р а з л и ч н ы х сред.
429
Приложение 1 ПЕРЕКЛЮЧЕНИЕ Р Е Ж И М О В РАБОТЫ ПРОЦЕССОРА Программа для переключения в защищенный режим и вывода в видвопемять пробелов на черном и белом фоне в защищенном и реальном режиме Для вывода использовать текстовый режим 80*25 В каждом режиме должно быть заполнено 13 и 12 строк соответственно. IDEAL Р586 MODEL TINY codeseg STRUC descriptor limit_0_15 dw 0 base 0_15 dwO base_16_23 db 0 access db 0 gran db 0 bese_24_31 db 0 ENDS descriptor
: ; ; : ; ;
,
младшие 16 б и т о в предела младшие 16 битов адресе 16-23 биты адреса байт доступа 16-19 биты предела и его размерность 24-31 биты адреса
CODE_ACCESS EQU Ю0110ЮВ; Байт доступа для кодового сегмента DATA_ACCE$S EQU 10010010В; Байт доступа для сегмента данных ; Структура для использования комвндои GDTR LABEL GDTADDR PWORD DW31 ;Предеп GDT~4тВ-1 DD ? Адрес начала GDT : GDT LABEL GDTTBL DWORD GDT_NULL descriptor <> ;0 GDT_PMCOD descriptor GDT_RM_COD descriptor GDT_PM_DAT descriptor <80"25'2-1,„DATA_ACCESS.W001111B,0>
;Kod
begin. MOV AX.@code MOVDS.AX ; Адрес начала сегмента для реботы в защищенном режиме ; Адрес начала кратен 16. поэтому смещение на учитывается ; PROT_MODE ' 16
XOR EAX, EAX MOV AX,PROT_MODE SHL EAX,4H MOV EBX, EAX SHR EAX, 16 MOV [GDT_PM_COD.base_OJ5], BX MOV [GDT_PM_COD.base_16_23],AL ; Адрес начала сегмента для перехода в реальный режим ; REAL_MODE * 16 + Смещение XOR ЕАХ,ЕАХ xorebx ebx movax ds shl eax, 4 movbx, offset REAL_MODE add eax, ebx МО V [GD T_ RM_ COD.base_0_ 15],aX SHR EAX,16 MOV [GDTRM_COD base_16_23],AL ; Адрес начала информации о GDT XOR EAX, EAX MOV AX,CS SHL EAX,4H xor ebx, ebx mov bx offset gdttbl ADD EAX,ebx MOV [DWORD PTR GDTADDR+2],EAX ; Загрузка GDTR LGDT [GDTADDR] ; Маскирование прерываний си ; Включение защищенного режима MOV ЕАХ, CRO OR ЕАХ,1 MOVCRO.EAX ; Переход на сегмент для заполнения половины экрана JMP FAR PTR 00008Н:0000Н ; Участок кода для возврата в реальный режим /аЬе/ real_mode word ; Отключение защищенного режима MOVEAX.CRO X0REAX.1 MOVCRO.EAX ; Сброс конвейера JMP FAR PTR Cont 431
370 ; Код для заполнения экрана Cont: : Разрешение прерываний STI MOV АХ. : режиме MOV ES. SUB EDI. .
в реальном режиме
0B800h
; Адрес видеопамяти в текстовом
АХ 0В8000Н
Будем записывать по 2 символа за одну команду, каждый символ в видеопамяти з а н и м а е т 2 байта младший байт — код символа. стерший атрибут, который формируется по правилу младшие 4 бита задают цвет символа (черный. О), стершие 3 бита - цвет фона (белый. 7) ; Количество 2-символьны* элементов в 12 строках равно 12 'ВО/2 MOV СХ. 12-80/2 ; Смещение для записи первого символа MW D/. 13 * 80 ' 2: Пропускаем 13 строк @For1 MOV [DWORD PTR ES.DI]. 70207020H ADD Dl 4 LOOP @ For 1 : Завершение Dos-программы MOV Ax.C4C00H :Dos program terminate INT21H . Сегмент для работы в защищенном режиме ; Сегмент выровнен нв границу параграфа. ; т е. адрес кратен 16 (PARA) 32-битный (USE32). кодов ("CODE ), видимый из других сегментов (PUBLIC) SEGMENT PROTJAODE PARA PUBLIC USE32 CODE' ASSUME CS.PROT MODE MOV AX.18H: Дескриптор сегмента видеопамяти MOVES.AX MOVED!.О MOV CX. 25 - 80 * 13/2 @For2: MOV [DWORD PTR ES:EDI].07200720H ADD EDI.4 LOOP @For2 ; Возврат на сегмент для перехода в реальный режим JMP FAR PTR ОООЮН.ОООООН ENDS PROT MODE END begin
Приложение 2
ПЕРЕКЛЮЧЕНИЕ З А Д А Ч . П О Л Я И Ф Л А Г И Флаг или поле Флаг занятости В для новой з а д а ч и
Команда JMP
Команда CALL
Команда IRE Г
Да. Должен быть о ч и щ е н перед этим
Не изменяется. Д о л ж е н быть установлен перед этим
Флаг занятости В Ф л а г о ч и щ а е т с я для старой з а д а ч и
Не изменяется. Д о л ж е н быть установлен
Флаг очищается
NT-флаг д л я новой задачи
Не изменяется
Устанавливается
Восстанавли вает значение из TSS новой задачи
NT-флаг д л я старой задачи
Не изменяется
Не изменяется
Очищается
Поле связи д л я новой задачи
Не изменяется
Устанавливаетс я р а в н ы м селектору для TSS старой задачи
Не изменяется
Поле связи д л я старой задачи
Не изменяется
Не изменяется
Не изменяется
Флаг TS в регистре CRO
Флаг устанавливается
Флаг устанавливается
Флаг устанавливается
Да. Должен быть очищен перед этим
433
Приложение 3
ИСКЛЮЧЕНИЯ IA-32 исключения
Тип
0
Fault
Опислние Д е л е н и е пя нуль (Divide Error Exception) Отладочное прерывание (Debup Exception)
1
Trap и л и fault
2
NMI
Немаскируемое прерывание
3
Trap
Точка останова (Breakpoint Exception)
4
Trap
Переполнение ( O v e r f l o w Exception]
5
fault
Выход за допустимые г р а н и ц ы при BOUND (Bound Rang е Exceeded Exception)
6
fault
Неправильная инструкция (Invalid Opcode Exception)
7
fautt
Блок F P U не доступен (No Math)
В
abort
Д в о й н а я ошибка (Double Fault Exception)1
10
fault
Неверный TSS (Invalid TSS)
11
fault
Нет сегмента в оперативной памяти (Segment Not Present)
12
fault
Ошибка при обращении к с т е к у (Stack Fault Exception)
13
fault
Общая о ш и б к а (Genera/ Protection Exception)
14
fault
Ошибка страничной адресации (Page Fault Exception)
fault
Ошибка при обращении к Блоку FPU (FPU Error)
17
fault
Ошибка в ы р а в н и в а н и я (Alignment Check Exception)
18
abort
Машинно-зависимая ошибка (Machine Check Exception)
10
fault
Ошибка SSE/SSIi2 (SIMD Floating Point Exception)
9
Резерв
15 16
20 3 1
Реяерв
Резерв
370 ' При обработке исключения возникло новое исключение.
Приложение 2
СТРУКТУРЫ ДЛЯ VFS Структура
о б ъ е к т а INODE
structf struct listhead i_hash; // Указатели на хеш-список struct listhead i_list; // Указатели на список inode struct list_head i_dentry; // Указатели на список dentry struct list head i_dirty^buffers; // Указатели на список измененных II буферов struct tist_head i_dirty_data_buffers; // Указатели на список I/буферов с измененными данными unsigned long ijno; //номер inode unsigned int i_count; //счетчик использования kdev_t i_dev; //идентификатор устройства umode_t i_mode; //Tun файла и права доступа nlinkt i nlink; //Количество hard links uid t i uid;//Идентификатор владельца gid_t i gid; // Идентификатор группы kdev t i rdev; //Идентификатор Real device of ft isize ; //Длина файла в байтах time_t i_atime; //Время последнего доступа к файлу time_t i_mtime; //Время последней записи в файл time t i ctime ; //Время последнего изменения inode unsigned int i_btkbits; //Размер блока в битах unsigned long i_blksize; //Размер блока в байтах unsigned long i_blocks; //Количество блоков в файле unsigned long inversion; //Номер версии, увеличивается //при каждом доступе struct semaphore i_sem; //Семафор для inode semaphore struct semaphore i_zombie; //Семафор для inode. Используется при //удалении или переименовании inode struct inode operations * i_op; // Таблица операций для inode struct file_operations * i_fop ; // Таблица операций для file struct super_ block * i sb; //Указатель на объект superblock wait_gueue_head_t i_wait; //Очередь ожидания для inode struct file_lock * i_flock; //Указатель на список заблокированных //файлов stmct address_space * i__mapping; //Указатель на адресное //пространство объекта struct address_space i_data address_space; //Объект для block // device file struct dquot ** i dquot; //Дисковые квоты для inode struct list_head i_devices; //Указатели на список inodes //для block device file 435
struct pipe inode info * i_pipe; //Используется. Если файл типа pipe struct blockdevice " i_bdev; //Указатель на драйвер блочного Itустройства struct chardevice 'icdev;//Указатель на драйвер строчного //устройства unsigned long i_dnotify_mask; //Битовая маска событий для каталоге struct dnotify^struct' idnotify; //Используется для directory //notifications unsigned long instate; //Флаги состояния inode unsigned int l_flags. //Флаги монтирования ФС unsigned char i_sock; //Истина, если файл -это соквт atomic_t t_writecount: //Счетчик использования для записывающих //процессов unsigned int i_attr_ flags;//Флаги создания файла и32 generation; //Номер eepct/u inode union и; //Информация, которая зависит от ФС }: С т р у к т у р а о б ъ е к т а FILE stmctFILE { struct tist head f list: // Указатель не список stmct dentry * f dentry;//Каталог для файла struct vfsmount' f vfsmnt; // ФС для файла struct filejopemtions ' f_op; И Указатель не таблицу операций // для файла atomic I fcount; // Счетчик использования unsigned int f_ flags;//Флаги mode_ t f mode; // Режим Доступа toffjt f_pos; // Текущее смещение для файла unsigned long f reeda; H Read-ahead flag unsigned long framax; //Maximum number of pages do be readehead unsigned long fraend; П File pointer after lest read-ahead unsigned long f_ralen;//Number of read-ahead bytes unsigned long frawin; // Number of read-ahead pages struct fown struct f_ owner; //Данные для асинхронного I/O unsigned int f_uid; // Идентификатор пользователя unsigned int fjgid: //Идентификатор группы mt f_error. //Код ошибки для с е т е в о й операции unsigned long f verslon://Версия. Автоматически увеличивается //после каждого обращения void ' private_data: // Необходимо для драйвера Ну struct kiobuf" f_lobuf'; //Дескриптор для буфера прямого доступа //к памяти long f_iobuf_lock; //Блокирование прямого доступа }: 370
С т р у к т у р а о б ъ е к т а т и п а DENTRY
struct DENTRY{ atomic! dcount; // Счетчик использования unsigned int d_ flags; // Флаги struct inode * d_inode; // Inode для файла struct dentry * d_parent; // Dentry-объект для родительского //каталога struct tist_head d_hash; // Указатели на список в хеш-таблице struct list head dlru; // Указатели на список неиспользуемых // объектов struct list_head d_child; // Указатели на список dentry-объвктов, //включенных в родительский каталог struct list_head dsubdirs; //Для каталогов, список dentry-объектов // подкаталогов struct list_head d_atias; // Список из ассоциируемых inod'oe (алиасов) int d_mounted; // Флаг равен 1, если и только если dentry - точка //монтирования ФС struct qstr d_name; // Имя файла unsigned long d_ time; // Испольуется функцией d rewalidate struct dentry_operations* d op; // Функции для Dentry struct super_block * d_sb; // Объект Superbtock файла unsigned long d_vfs_flags; // Флаги кэширования для Dentry void * d fsdata; //Данные, которые зависят от ФС unsigned char * djname; //Адрес корткого имени файла };
437
ЛИТЕРАТУРА 1. Рекомендации по преподаванию информатики в универси тетах: Пер. с англ. СПб.: Питер, 2002. 372 с. 2. С и с т е м н о е п р о г р а м м н о е о б е с п е ч е н и е / А. В. Гордеев. А. Ю- Молчанов. — СПб.: Питер, 2001. — 736 с. 3 . Р и х т е р Д ж . W I N D O W S д л я профессионалов: создание эффективных Wiп32-пpилoжeний с учетом с п е ц и ф и к и 64-разрядной версии WINDOWS. — СПб.: Питер, 2001. 752 с. 4 . Р и х т е р Д ж . , К л а р к Д ж . Д . Программирование серверных п р и л о ж е н и й д л я M i c r o s o f t W I N D O W S 2 0 0 0 . — СПб.: Питер, 2001592 с. а. Хоар Ч. Взаимодействующие последовательные процессы- — М.: Мир, 1989. — 2 6 4 о. б. Краковяк С. Основы организации и ф у н к ц и о н и р о в а н и я ОС ЭВМ. — М-: Мир, 1988. — 4 8 0 с. 7. Шоу А. Логическое п р о е к т и р о в а н и е о п е р а ц и о н н ы х систем. М.: Мир, 1981. — 3 6 0 с . 8. Готье Р. Руководство по операционной системе UNIX. М.: Финансы и статистика, 1985. — 232 с. 9. Ц и к р и т з и с Д . , Бернстайн Ф. Операционные системы. — М.: Мир. 1977. — 336 с. 10. Кейолер С. Проектирование операционных систем для малых ЭВМ. — М.: Мир, 1986. — 6 8 0 с. 11. Сайт LowLeveI.ru 12. Кормен Т., Лейзерсон Ч . , Ривест Р. Алгоритмы. Построение и анализ. — М.: МЦНМО. 2000. — 9 6 0 с. 13. Деревянно А. С.. Солощук М. Н. Операционные системы: Учебн. пособие. Харьков: Х П И , 2003. — 574 с. 14. Inside Microsoft W I N D O W S 2000. Theard Edition eBook. 15. Undestanding LINUX K e r n e l By Daniel P. Bovet, Marco Cesati. — 784 p.
ПРЕДМЕТНЫЙ УКАЗАТЕЛЬ
А Адресное пространство, 4 8 ; 2 0 3 Алгоритм — банкира, 1 1 2 — близнецов (buddy s y s t e m algorithm), 221 — выгрузки страниц, 2 0 7 — Деккера, 1 0 8 — обработки прерываний, 261 — обращения к файлу из корневого каталога, 3 0 5 — определения адреса в кэш-памяти, 2 1 3 — планирования, 1 3 2 — с ж а т и я файлов, 3 1 7 — создания потока, 153 — управления страницами, 2 0 9 Архитектура памяти, 2 2 3 Асинхронный р е ж и м ввода-вывода, 17; 65; 3 4 9 Атомарная операция, 92
В Взаимное исключение, 105 Взаимоблокировка (тупик), 105 Виртуальная м а ш и н а , 30 Винчестер — адресация секторов, 2 7 1 ; 2 6 8 — логическая структура, 2 6 8 — программный доступ к секторам, 271 — разделы, 2 6 9 Внешние устройства — алгоритм обработки запроса, 261 — блочные устройства, 2 5 9 ; 2 6 5 — буфер, 264 — винчестер, 2 6 8 — виртуальные внешние устройства, 2 7 3 — дискета, 2 6 6 — классификация, 2 5 9 — кэширование, 2 7 3 — метод опроса, 2 6 0 — р е ж и м прерывания, 2 6 1 — р е ж и м ы управления, 2 6 2 — символьные устройства, 2 5 9 — стратегии буферизации, 2 6 4 Вытесняемая многозадачность, 28
д
Дискета — логическая структура, 2 6 6 — программный доступ к секторам, 2 6 8 Диспетчер процессов/потоков (Process Manager), 14 Диспетчеризация, 130 Дополнительные потоки д а н н ы х (NTFS), 3 2 1 Драйвер, 13 — архитектура д л я блочного устройства, 2 6 2 ; 2 6 5 — выделение памяти в драйвере, 388 — драйверы д л я DOS, 36; 361 — драйверы д л я W I N D O W S NT (2000), 362 — загрузка драйвера, 3 9 6 — история создания, 3 6 0 — информация об установленных драйверах, 3 6 9 — классификация, 3 7 5 — к о м п и л я ц и я , компоновка, 3 9 5 — определение, 3 6 0 — очереди драйверов, 72; 75 — п р и м е р драйвера, 3 9 0 — разработка, 3 7 5 — с п и с к и устройств, 72 — стандартный пакет IRP, 3 6 7 — стартовая ф у н к ц и я DriverEntry, 376 — структура, 3 7 6 -— точки входа, 3 8 4 — функции-обработчики (...Dispatch...), 3 8 1 — ф у н к ц и и д л я базовых операций (irp mj ...), 3 8 3 — ф у н к ц и и обработки завершения (...CompletionRoutine), 3 8 1 -— экспортируемые ф у н к ц и и . Имена, 3 6 6 — WDM-драйверы, 3 6 9 — VXD-драйверы, 3 6 2 3 Завершение ввода-вывода, 3 5 1 Завершение потока (способы), 144 Завершение процесса (способы), 1 3 5
439
3 идя ние. 1 4 8 завершение, 151 и н ф о р м а ц и я о з а д а н и и . 151 — с о з д а н и е , 148 Задачи, 77 алгоритм переключения. 80; 83 д е с к р и п т о р сегмяита с о с т о я н и я з а д а ч и (TSSD). 8 4 с е г м е н т с о с т о я н и я з а д а ч и (TSS). 84 шлюз задачи. 89 Ж Ж д у щ и е т а й м е р ы , 186 Жесткие ссылки (HardLink), 322 Журнал, 326 И Интерфейсы I/O. 70 И с к л ю ч е н и я . 70; 4 2 0 — обработка з а в е р ш е н и я { finally). 4 2 1 обработка и с к л ю ч е н и я . 4 2 5 — структурная обработка. 420 К К а р т а вводе-вывода. 8 6 К в а н т времени. 8 6 : 1 3 2 : 1 3 8 Квоты д и с к а . 3 0 9 К л а с с и ф и к а ц и я ОС. 2 7 Клиент-сервер. 25 К о м а н д н а я с т р о к а . 141 Корневой к а т а л о г . 3 0 4 К р и т и ч е с к а я с е к ц и я . 106; 1 7 0 К р и т и ч е с к и й ресурс, 1 0 6 Коммуникация между процессами, 124 — к л м е и т - с е р и е р н а я м о д е л ь , 127 почтовый ЯЩИК. 1 2 6 с о о б щ е н и я , 124 Контроллер п р е р ы в а н и и (1'1С). 6 7 у с о в е р ш е н с т в о в а н н ы й < AP IC), 67 устройства. 1 2 : 6 3
М
Магкироваиие прерываний, 67 М е н е д ж е р вводя-выводя. 23; ЗС6 Мвогоавдачный режим, 81 М н о г о п о л ь з о в а т е л ь с к и й р е ж и м . 14 Многопроцессорный режим. 18 — доступ к п а м н т и N LIMA. 19 масштабирование. 20 — н е с и м м е т р и ч н а я система (ASMP). 2 0
с и м м е т р и ч н а я система (SMP). 19 с н и и - б л о к и р о в к а (Spin Lock), 127 М о д у л ь у п р а в л е н и я п а м я т ь ю (Memor y m a n a g e r ) . 15; 1 9 1 Монитор, 114 — недостатки, 119 о п р е д е л е н и е . 114 — п и к е т н ы й . 10 п р и м е р ы использования. 116 функции.115 М о н и т о р и н г и з м е н е н и й «1>С. 3 0 0 М у л ь т и п р о г р а м м и р о в а н и е . 13 М ь ю т е к с ы , 181
Н
Нпчып.лил з а г р у з к и О С . 3 9 Невытесаяешая многозадачность, 81 О Очередь — г о т о в ы х п о т о к о в . 131 д л я у р о в н е й п р и о р и т е т о в . 131 — д р а й в е р о в . 72 — запросов к устройству, 2 2 ; 2 6 5 : 282 используемых страниц. 207 — обработчиков по т а й м е р у . 187 о т л о ж е н н ы х ф у н к ц и й . 105; 127; 333 порта з а в е р ш е н и я , 3 3 2 11]|<>ЦЛ4 ион. 1 1 4 : 1 2 0 ; 131; 1 3 2 сообщений, 37; 126 Л Память — адресация. 195 — алгоритм управления страницами. 2 0 9 алгоритмы выгрузки страниц, 207 — а п п а р а т н ы е средства управления. 195 — архитектура, 223 б л о к у п р а в л е н и я . 191 — в и р т у а л ь н а я . 192; 2 2 5 ; 2 3 5 выделение памяти. 2 1 8 — задниие с т р я я ч ч в о й а д р е с а ц и и , 206 — копирование только при записи (сор>-on-write). 1 9 5 — «кучи* (Heap). 249 — кэширование. 211 кэш-память. 211 методы управления страницами, 208 370
— механизмы работы, 2 3 5 — отображение файлов (FileMapping), 2 4 2 — пробуксовка, 2 0 9 — программное определение параметров, 2 1 6 — прямой доступ, 2 7 4 рабочее множество, 2 0 8 — регионы, 2 2 3 — сегментная адресация, 1 9 3 состояние страниц, 2 3 1 — страничная адресация, 194; 2 0 2 — страничный файл, 2 2 4 — стратегия подкачки и выгрузки страниц, 2 0 7 — фрагментация, 2 0 2 Пакетная обработка, 10 Параллелелизм, 79 — в системах аппаратного оборудования, 79 — вытесняющая многозадачность, 80 — невытесняющая многозадачность, 80 Пакетный монитор, 10 Переключение м е ж д у реальным и защищенным режимами, 430 Переменные о к р у ж е н и я , 1 4 1 Планирование, 130 — адаптивно-рефлекторное, 1 3 5 — алгоритмы, 1 3 2 — вытесняющее и невытесняющее, 135 — очереди с обратной связью, 1 3 3 — приоритетное, 1 3 3 — политики планирования, 135 — циклическое, 1 3 2 Поддержка 64 битных процессоров, 20; 1 2 4 Поток — алгоритм создания, 153; 154 — завершение, 156 — контекст, 1 6 0 — определение временных интервалов, 1 5 7 — потоковая ф у н к ц и я , 1 5 4 — приостановка и возобновление, 157 Прерывания, 65 — при параллельном исполнении, 104 Префикс LOCK, 93 Принципы разработки операционных систем — иерархический метод, 30
441
— методология ядра, 33 Приоритет, 1 4 2 — динамический, 134 — класс, 1 4 2 — статический, 1 3 4 — уровень, 1 4 2 П р о г р а м м н ы й интерфейс ОС (API), 43 Процесс — абстрактное определение, 96 — завершение процесса, 1 4 6 — интерактивный, 1 3 6 — и н ф о р м а ц и я о процессах, 1 4 7 — классификация, 98; 138; 1 3 9 — контекст процесса, 97 — логическое время выполнения, 106 — пакетный, 1 3 6 — приоритет процесса, 1 4 2 — пропускная способность, 81 — процессы реального времени, 16; 1 3 6 — процессы-службы, 1 3 9 — переключение контекстов, 1 0 3 — создание, 1 4 3 — состояние, 94 — структуры д л я определения, 99 — статические и динамические характеристики, 1 3 1 — типы процессов, 1 3 6 — уровень привилегии, 1 3 4 — холостой, 1 3 2 Прямой доступ к памяти, 72 Р Реактивность, 16; 82 Регистр флагов, 84 Р е ж и м р а з д е л е н и я времени, 2 0 Р е ж и м ф у н к ц и о н и р о в а н и я процессора — з а щ и щ е н н ы й , 49 — пользователя, 32; 47 — реальный, 48 — ядра, 32; 47 Ресурсы, 4 2 С Свойства операционных систем, 26 Семафор — понятие, 1 1 9 — использование д л я критической секции, 1 1 9 — распределение м н о ж е с т в а ресурсов, 1 2 2 Серверные о п е р а ц и о н н ы е с и с т е м ы , 16
Сериализация. 93 Сжатие файлов. 3 1 8 С и н х р о н и з а ц и я , 109 — атомарный доступ потоков. 1 6 6 ж д у щ и е таймеры потоков. 175; 186 критическая с е к ц и я . 170
мьютексы, 181
объекты ядра. 175 с е м а ф о р ы . 184 — событии. 1 7 7 - функции ожидания, 176 Синхронный режим вводе-выводе. 64:341 Системные вызовы. 21 Системы реального времени, 16 События. 177 Спин-блокировка (SpinLock). 127 Стратегии буферизации. 76 Стратегия LRU. 6; 213: 405 Сценарии. 406 — выполнение. 415 — классификации операторов. 4 0 7
— передача пераыетров. 410
— п о л у ч е н и е п о м о щ и по к о м а н дам. 408 разнотипен ни и ц и к л ы в с ц е н а рии. 4 1 1
Т
Таблица прерываний. 68 Т у п и к (взаимоблокировка). 111 У Управление памятью. 191 Уровень п р и в и л е г и и — д л я к о м а н д и д а н н ы х процессод л я о п е р е ц и й ввода-вывода ( l O P L ) . 38; 8 6 У с л у г и б е з о п в с в о с т и . 18 Устройства блочные. 2 5 8 — символьные, 259
Ф
Ф а й л . 338 п о и с к , 344 размер. 3 4 2 Файловая система. 277 змртунльная ФС. 280; 284 вмсстшшилинасмость, 3 3 1 — демонтирование, 292 задачи С У Ф . 2 7 7 каталог. 282 — компакт диск.332
- компоненты. 281 - корневая ФС, 294 лпгическяя организация, 2280 метаданные. 2311 монтирование, 292 система управления файлами. 277 - специализированная ФС. 285 структуры данных, 286 ФУНКЦИЯ для обращения к драйверу — DeviceloCkmtrol. 43
— loctl. 43
- д л я управления памятью. 223 ожидания. 190 операционной с и с т е м ы . 2 1 потоковая. 154 Ш Шифрование. 3 2 0 Я Ядро микроядро. За монолитное. 34 акзоядро. 37
AcidDevice. 378
Л
Closellandle. 339 CloseServireHfl ndle. 4 0 3 C o m p a c t Disc File S y s t e m , 3 1 0 ControlServirp. 403 CPCID. 94; 216 C r e s t e F i l e . 33S CredteFilcMoppiiiR. 2 4 1 CreateHardLmk. 322 CreateloCompletionPort. 333 CreateService. 400 Completion Routine. 187 D DoviccIoCoiitrnl, 3 7 3 DMA. 72; 2 7 4 DMAC. 72: 2 7 4 DrivorEutry. 376
E
E n c r y p t F i b S y s t e m (EKS). 18; 3 2 0 FindCloseChangeNotification. 326 FiiiilPirslChfliigi-NolificHlton. 3 2 6 FindNextChangeNotification. 326 442
G GetDiskFreeSpace, 3 3 4 GetDiskFreeSpaceEx, 3 3 5 GetDriveType, 334 GetFileSize, 3 4 2 GetLogicalDrives, 3 3 3 GetLogicalDriveStrings, 3 3 3 GetOverlappedResult, 3 5 1 GetQueuedCompletionStatus, 3 5 5 GetProcessHeap, 250; 2 5 4 GetSystemlnfo, 2 2 5 GetVolumelnformation, 3 3 3 GlobalMemorvStatusEx, 2 2 8 — FAT12, 3 0 0 — FAT16, 300; 3 0 7 — FAT32, 300; 3 0 7 FileTimeToLoealFileTime, 3 4 6 FileTimeToSystemTime, 3 4 7 FindClose, 3 4 6 FindFirstFile, 3 4 4 FindNextFile, 3 4 6 H HardLink. 3 2 2 HeapAlloc, 2 5 2 HeapCompact, 2 5 6 HeapCreate, 2 5 1 HeapDestroy, 254 HeapFree, 254 HeapLock, 2 5 6 HeapSize, 2 5 3 HeapUulock, 2 5 6 HeapValidate, 2 5 5
1
IoAttachDeviceToDeviceStack, 3 8 0 IoCreateDevice, 3 7 9 l/O-Manager, 3 6 8 I/O request packet (IRP), 3 6 7
M MBR, 2 6 8 MapViewOfFile, 2 4 4 Master File Table, 3 1 1 N NTFS, 308
O
OpenFileMapping, 2 4 4 OpenSCMaiiager, 3 9 9
PIC,67
Q QueueUserAPC, 3 5 5
R ReadDirectoryChangesW, 3 2 5 ReadFile, 3 4 1 ReadFileEx, 352 RegCloseKey, 3 7 1 RegEnumKeyEx, 371 RegOpenKeyEx,371 RegQuerylnfoKey, 371 RtllnitUnicodeString, 379 S SetFilePointer, 2 6 8 SeiVolumeLabel, 3 3 4 Sparse, 3 1 6 StartService, 4 0 2 SysternTimeToFileTime, 3 4 7 VFS, 4 0 4 VirtualAlloc, 2 3 5 VirtualQueryEx, 2 2 9 W WriteFile, 341
LBA, 2 7 1
443
Навчальне
видання
БОНДАРЕНКО Михайло Федорович КАЧКО Олена Григорівна
О П Е Р А Ц І Й Н І
СИСТЕМИ
Навчальний посібник Російською
Редактор
мовою
Н. В. Ерик
Комп'ютерна верстка О. А. Федосеєвої Дизайн обкладинки А. В. Пивоварова
Підписано до д р у к у 0 1 . 0 2 . 2 0 0 6 . Формат 60 > 9 0 / 1 6 . Папір офсетний. Гарнітура ЗсЬооІВоокС. Друк ризографічний. Умов. друк. арк. 2 7 , 7 Тираж 4 0 0 прим. Зам. №
Видавництво «Компанія СМІТ» 6 1 1 6 6 , м. Харків, просп. Леніна,14 Тел. 8 ( 0 5 7 ) 7 1 7 - 5 4 - 9 4 , 7 0 2 - 0 8 - 1 6 Факс: 8(057) 702-13-07. Е - т а і І : Ьоок@Бтїї.кЬагкоу.иа ЬМр://\у\т.втіі;-Ьоок.сот Свідоцтво про внесення суб'єкта видавничої справи до державного реєстру видавців, виготівників і р о з п о в с ю д ж у в а ч і в видавничої продукції ДК № 4 3 5 від 2 6 . 0 4 . 2 0 0 1 .
Друк — ФОП «ВасильєваН. В.» м. Харків, просп. Леніна, 14 Тел. 8(057) 702-13-07
I