![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Синхронизация на уровне исполнительной системы ⇐ ПредыдущаяСтр 3 из 3
Программному обеспечению за пределами ядра также необходима синхронизация доступа к глобальным структурам данных в многопроцессорной среде. Например, у диспетчера виртуальной памяти есть только одна база данных страничных фреймов, с которой он работает как с глобальной структурой данных, а драйверам устройств нужна возможность монопольного доступа к своим устройствам. При помощи функций ядра, исполнительная система может создавать, получать и освобождать спин-блокировку. Однако спин-блокировки только частично удовлетворяют потребность исполнительной системы в механизмах синхронизации. Так как ожидание спин-блокировок буквально останавливает процессор, их можно использовать только при следующих строгих условиях: • Доступ к защищенному ресурсу должен осуществляться быстро и без сложного взаимодействия с другим кодом. • Критическая секция не может откачиваться из памяти, не может обращаться к нерезидентным данным, не может вызывать внешние процедуры (включая системные сервисы) и не может генерировать прерывания и исключения. Эти ограничения довольно серьезны и не всегда их можно удовлетворить. Более того, помимо взаимного исключения исполнительной системе необходимо выполнять синхронизацию других типов, и она должна предоставить механизмы синхронизации для пользовательского режима. Рис. 7-14. Ожидание диспетчерского объекта. Ядро предоставляет исполнительной системе другие механизмы синхронизации в форме объектов ядра, которые называются диспетчерскими объектами. Поток может синхронизироваться с диспетчерским объектом путем ожидания у его описателя. Это заставляет ядро приостановить поток и изменить его состояние с " исполняющийся" на " ожидающий", как показано на рис. 7-14. Ядро изымает поток из очереди готовности диспетчера и более не рассматривает его в качестве кандидата на выполнение. Поток не может возобновить выполнение, пока ядро не изменит его состояние с " ожидающий" на " готовый". Такое изменение происходит, когда состояние диспетчерского объекта, у описателя которого ждет поток, изменится с " занят" на " свободен" (например, когда какой-нибудь другой поток установит объект-событие). Ядро отвечает за оба типа переходов между состояниями. Некоторые диспетчерские объекты ядра и системные события, вызывающие изменения их состояния, показаны на рис. 7-15. Каждый тип диспетчерского объекта предоставляет особый тип синхронизации. Например, объект-мьютекс обеспечивает взаимное исключение; семафор работает как шлюз, через который может проходить переменное число потоков, — это бывает полезно, когда имеется несколько идентичных ресурсов. События могут использоваться либо для уведомления о том, что было выполнено некоторое действие, либо для реализации взаимного исключения. Пары событий — это средство поддержки ядром быстрого LPC, оптимизированной формы передачи сообщений, а подсистеме Win32. Таймеры " срабатывают" по истечении заданного интервала времени. Поток может ждать завершения другого потока, что бывает полезно для координации действий между взаимодействующими потоками. Все вместе, диспетчерские объекты ядра предоставляют исполнительной системе большую гибкость в синхронизации исполнения. Синхронизационные объекты, доступные в пользовательском режиме, получают свои возможности синхронизации от диспетчерских объектов ядра. Каждый синхронизационный объект, видимый пользовательскому режиму, инкапсулирует в себе по крайней мере один диспетчерский объект ядра. Приведенный ниже пример установки события демонстрирует взаимодействие синхронизации с планированием потоков: 1. Поток пользовательского режима ждет у описателя объекта-события. 2. Ядро изменяет состояние потока с " готовый" на " ожидающий", после чего помещает поток в список потоков, ждущих данное событие. 3. Другой поток устанавливает событие. 4. Ядро просматривает список потоков, ждущих события. Если для некоторого потока выполнены условия прекращения ожидания, то ядро изменяет его состояние с " ожидающий" на " готовый". Если это поток переменного приоритета, то ядро может также поднять его приоритет. 5. Так как к исполнению готов новый поток, то диспетчер выполняет перепланировку. Если он находит выполняющийся поток, приоритет которого ниже приоритета нового потока, то низкоприоритетный поток вытесняется путем генерации программного прерывания для переключения контекста на новый поток. Рис. 7-15. Некоторые диспетчерские объекты ядра.
6. Если ни на одном из процессоров нельзя выполнить вытеснение, диспетчер помещает готовый поток в свою очередь, чтобы направить его на выполнение позднее.
Восстановление после сбоя питания Главной задачей при разработке NT было сделать ее устойчивой и надежной ОС. Здесь можно задать вопрос: насколько далеко должна заходить надежность? Хотя архитектура обработки исключений помогает защитить ОС изнутри, что произойдет, если вмешается внешний фактор, нарушающий ее целостность? Одной из форм внешней угрозы являются пользователи-нарушители, пытающиеся обойти системный контроль доступа. Другая потенциальная угроза — программы, пытающиеся израсходовать все системные ресурсы. Для борьбы с первой опасностью предназначена система защиты Windows NT, а ограничения квот на ресурсы помогают бороться со второй. Однако остается еще одна опасность — сбой питания. Для сбоя питания в ядре NT зарезервировано второе по старшинству приоритета прерывание. Оно уведомляет о проблеме в источнике питания, чтобы система могла выполнить останов как можно более корректно. Если бы ни эта процедура, вся работа, выполнявшаяся в момент аварии, могла бы пропасть, Исполняющиеся программы могут закончить или не закончить свою работу и могут оставить постоянные ресурсы (такие как файлы), которые они использовали, в восстановимом или в невосстановимом состоянии. При сбое питания у ОС остается время только на то, чтобы начать процедуру останова. Если компьютер оборудован резервными батареями для памяти, данные можно восстановить, когда питание будет подано вновь. Выполнявшиеся задачи могут быть перезапущены либо продолжены, в зависимости от их состояния на момент сбоя. (Конечно, при отсутствии резервных батарей такое восстановление невозможно.) Перезагрузки регистров и возобновления исполнения недостаточно для полного восстановления системы. Так как устройства ввода-вывода работают независимо от остальной ОС, для восстановления после сбоя питания им требуется следующая поддержка со стороны ядра: • Они должны быть переинициализированы, когда питание восстановится. • Они должны уметь определять, имел ли место сбой питания. Эти средства предоставляются двумя управляющими объектами ядра. Объекты-уведомления питания (power notify objects) позволяют драйверам устройств зарегистрировать процедуру восстановления, которую ядро будет вызывать при возобновлении питания. Драйвер устройства определяет, что должна делать эта процедура; в общем случае она выполняет повторную инициализацию устройства и перезапуск прерванных операций ввода-вывода. Чтобы зарегистрировать процедуру восстановления после сбоя питания, драйвер создает объект-уведомление питания, вызывает ядро для инициализации объекта указателем на процедуру, после чего снова вызывает ядро для добавления объекта в очередь, контролируемую ядром. При восстановлении питания ядро просматривает эту очередь и вызывает все процедуры по порядку. Ядро предоставляет еще один управляющий объект, используемый драйверами устройств, объект-состояние питания (power status object). Создав такой объект и добавив его в другую очередь ядра, драйвер может определить перед началом операции, которую нельзя прервать (например, запись данных в регистр устройства), не произошел ли сбой питания. Если он произошел драйвер не выполняет операцию.
|