Реализация многозадачности на однопроцессорных компьютерах

На главную

Математика
Функции и их графики
Пределы
Производные
Векторная алгебра
Корни уравнения
Кривые и поверхности
Комплексные числа
Математическая логика
Дифференцирование и
интегральное исчисление
Дифференциальные уравнения
Брутальный характер
архитектуры
Интегралы
Курсовые задания
Применение интегралов
Теория функций
комплексного переменного
Двойные интегралы
Физические задачи
Элементарная математика
Математический анализ
Степенные ряды
Вычисление пределов
Типовой расчет
Подготовка к экзамену
Примеры решения задач
Лекции матан
Правило Лопиталя
Элементы теории кривых
Производные и дифференциалы
высших порядков
Непрерывные функции
Предел функции
Последовательности
Формула Тейлора
Определенные интегралы
Кратные интегралы
Тензоры
Интегралы, зависящие
от параметра
Элементы теории поля
Криволинейные интегралы
Тройные интегралы
Задачи по Кузнецову
Вычислить предел
Построить график
Комбинаторика
Ядерная физика
Cвойства атомных ядер
Ядерные реакции
Модели атомных ядер
Задачи по физике
Механика
Термодинамика
Электростатика
Радиоактивность

Геометрическая оптика

Квантовая механика
Атомная физика
Класическая физика
Кинематика
Волновая и квантовая оптика
Электромагнитное и
электростатическое поле
Примеры решения
физических задач
Электромагнетизм
II семестр физики
III семестр физики
Потенциал
Электpостатика

Теория ОС

Классификация ОС
Представление данных
Машинные языки
Загрузка программ
Управление памятью
Виртуальная память
Внешние события
Параллелизм
Реализация многозадачности
Внешние устройства
Драйверы устройств
Файловые системы
Безопасность
Обзор архитектур ОС
Сетевые ОС
Корпоративные ИС
Протоколы TCP/IP
Брандмауэры
Учебник FTP
Системы безопасности
Windows 2000
Windows 2003
Linux
Архитектура ЭВМ
NT 5.0 Справка
Основы Интернет
Атака через Internet
Основы защиты
Компьютерные сети
Введение в КС
Принципы построения ВС
Local Area Network
Монтаж сети
Передача дискр. данных
Базовые технологии ЛС
Построение локальных сетей
Сетевой уровень
Глобальные сети
Средства анализа
Топология ЛС
Глобальные КС
Глоссарий
Информатика
Турбо Паскаль
Процедуры и функции Pascal
Pascal Курс лекций
Базы данных
Язык запросов SQL
Программирование на СИ
Логическое программирование
Примеры программирования

 

Исполняя системный вызов, пользовательская программа передает управление ядру. С понятием ядра — комплекса программ, исполняющихся в привилегированном (системном) режиме процессора, — мы уже сталкивались в разд. Системы с базовой виртуальной адресацией и главе 5. Практически во всех современных системах ядро представляет собой единый процесс — единое адресное пространство. Но организация взаимодействия между нитями этого процесса в различных системах устроена по-разному.
Три основные группы нитей, исполняющихся в режиме ядра, — это, во-первых, обработчики прерываний, во-вторых — обработчики системных вызовов со стороны пользовательских процессов и, в-третьих, — нити, исполняющие различные внутренние по отношению к системе работы, например, управление дисковым кэшем. В документации фирмы Sun нити этих трех групп в ядре Solaris называются, соответственно, исполняющимися в контексте прерывания (interrupt context), в пользовательском контексте (user context) и в контексте ядра (kernel context, или контексте системы) [docs.sun.com 805-7378-10].
Далее мы будем называть последние две категории нитей, соответственно, пользовательскими и системными, хотя и те, и другие исполняют системный код в системном адресном пространстве.
Обработчики прерываний всегда представляют собой особую статью — система практически никогда не имеет контроля над тем, когда возникают внешние события, зато практически всегда обязана обрабатывать эти события по мере их появления. Поэтому обработчики прерываний получают управление по необходимости.
В то же время, порядок получения управления пользовательскими и системными нитями в ряде ситуаций находится под контролем системы. Планировшик является частью ядра и модули системы вольны включать его и выключать по мере необходимости. Практически всегда его выключают на время работы обработчика прерывания, но некоторые системы делают это и при активизации других нитей ядра.
Полное выключение планировщика на время работы ядра фактически означает что система не реализует внутри ядра вытесняющей многозадачности. Системные и пользовательские нити в этом случае являются сопрограммами а не нитями в полном смысле этого слова.
Эта архитектура, называемая монолитным ядром, привлекательна примерно тем же, чем привлекательна кооперативная многозадачность на пользовательском уровне: любой модуль ядра может потерять управление лишь в двух случаях — при исполнении обработчика прерывания или по собственной инициативе. Благодаря этому разработчик модуля может не беспокоиться о критических секциях и прочих малоприятных аспектах доступа к разделяемым данным (кроме, разумеется, случаев, когда разделяет данные с обработчиком прерывания).
Платить за эти преимущества приходится значительными сложностями при переносе системы на многопроцессорные машины и невозможностью реализовать режим реального времени. Действительно, код ядра, написанный в расчете на кооперативную многозадачность, не может быть реентерабельным, поэтому такая система в то время, когда исполняется какая-то из ее нитей, не может обрабатывать системные вызовы. Следовательно, она не может иметь пользовательские процессы с приоритетом выше, чем у нитей ядра — а именно такие процессы нужны для поддержки приложений реального времени.

Примечание
Те из читателей, кто когда-либо пытался реализовать обработку аппаратных прерываний под MS/DR DOS, должны быть хорошо знакомы с этой проблемой. Вопреки хакерскому фольклору, нереентерабельность ядра DOS связана вовсе не с переустановкой указателя стека при входе в обработчик прерывания 21h, а именно с тем, что ядро работает с разделяемыми данными, но не предоставляет собственных средств для взаимоисключения доступа к ним.

Впрочем, если нам не требуется реальное время и перед нами не стоит задача обеспечить равномерное распределение системных нитей между процессорами симметрично многопроцессорной машины, монолитное ядро вполне приемлемо. Большинство систем семейств Unix (фактически, все широко распространенные системы этого семейства, кроме System V R4) и Win32, OS/2 и ряд других систем общего назначения более или менее успешно ее используют.
Альтернативной монолитным ядрам является микроядро. Микроядерные системы реализуют вытесняющую многозадачность не только между пользовательскими процессами, но и между нитями ядра.

Микроядро QNX
Классическая реализация микроядра, QNX, состоит из вытесняющего планировщика и примитивов гармонического межпоточного взаимодействия, средств для обмена сообщениями send и receive. Эти примитивы, конечно же, сами по себе не могут быть реализованы реентерабельным образом, однако они просты, содержат очень мало кода, исполняются быстро, и на время их исполнения система просто запрещает прерывания.
Все остальные модули системы с точки зрения микроядра представляют соб полностью равноценные нити. То, что некоторые из этих нитей исполняю в пользовательском, а другие — в привилегированном режиме доступа микC" ядру совершенно неинтересно и не влияет на их приоритет и класс планировани QNX разрабатывался для приложений реального времени, в том числе и лл использования во встраиваемых микропроцессорных системах; но, благодап компактности и фантастической производительности, эта ОС иногда заменяв системы общего назначения. Микроядро QNX действительно заслуживает на звания микро, поскольку занимает всего 12 килобайт кода и полностью входит в кэш первого уровня даже старых процессоров архитектуры х86. Все остальные модули ядра — драйверы внешних устройств, файловых систем, сетевых протоколов, имитация API систем семейства Unix — динамически загружаются и выгружаются и не являются обязательными (если, конечно, приложение не требует сервисов, предоставляемых этими модулями). Благодаря этому ОС может использоваться во встраиваемых приложениях с весьма небольшим объемом ПЗУ.

Микроядро транспьютера
Другим примером классического микроядра является транспьютер. Микропрограммно реализованное микроядро транспьютера содержит планировщик с двумя уровнями приоритета и средства для передачи данных по линкам.

Микроядро Unix SVR4
Другие системы микроядерной архитектуры, например Unix System \/ Release 4.x (на этом ядре построены такие ОС, как Sun Solaris, SCO UnixWare, SGI Irix), предоставляют нитям ядра гораздо больше примитивов межпроцессного взаимодействия — в частности, мутексы. Ядро у этих систем в результате получается не таким уж "микро", но нашему определению это никоим образом не противоречит.
Важно подчеркнуть, что приведенное определение не имеет отношения к ряду других критериев, которые иногда (например, в дискуссиях в публичных компьютерных сетях, а нередко и в публикациях в более или менее серьезных журналах) ошибочно принимают за обязательные признаки микроядерной архитектуры. Отчасти эта путаница, возможно, создавалась целенаправленно, потому что в середине 90-х "микроядро" стало популярным маркетинговым слоганом, и поставщикам многих ОС монолитной или эклектичной архитектуры захотелось получить свою долю выгоды от возникшей шумихи.
Способ сборки ядра (динамическое или статическое связывание ядра с дополнительными модулями) и возможность динамической загрузки и выгрузки модулей без перезагрузки системы к микроядерности не имеют никакого отношения. Вполне микроядерная SCO UnixWare по умолчанию предлагает собирать ядро в единый загрузочный файл /stand/unix (хотя, впрочем, и поддерживает динамическую загрузку модулей). Напротив, не то, что монолитная, а кооперативно многозадачная Novell Netware замечательным образом умеет загружав и выгружать на ходу любые модули, в том числе и драйверы устройств (выгружать, разумеется, лишь при условии, что модуль никем не используется).
Один из корней этих заблуждений состоит в том, что в большинстве других контекстов антонимом "монолитной" архитектуре считается архитектура модульная. Таким образом, любой признак, свидетельствующий о том, что ядро ОС имеет модульную структуру, считается признаком микроядерности. В данном случае, однако, дихотомия "монолитность/микроядерность" говорит не о наличии или отсутствии в ядре более или менее автономных модулей или подсистем, а о принципах взаимодействия между этими модулями или подсистемами или, точнее, об одном аспекте этого взаимодействия: о том, что в монолитных ядрах взаимодействие происходит синхронно или преимущественно синхронно, а в микроядре — асинхронно.
Совсем уж наивно было бы отказывать Solaris в праве называться микроядерным на том основании, что файл /kernel/genunix у этой системы имеет размер около 900 килобайт. Ведь, кроме собственно микроядра — планировщика нитей и примитивов взаимодействия между ними — этот файл содержит также диспетчер системных вызовов, систему динамической подгрузки других модулей ядра (см. разд. Загрузка самой ОС) и ряд других обязательных подсистем.

Микроядро концептуально очень привлекательно, но предъявляет к разработчикам модулей ядра известные требования. Например, в документе [docs.sun.com 805-7378-10] основное из этих требований — не забывать о том, что ядро Solaris многопоточное, и любая из нитей ядра может быть в любой момент вытеснена [практически любой] другой нитью — высказывается на второй странице, а выводам, которые из этого следуют, посвящена целая глава.
При разработке системы с нуля это само по себе не представляет проблемы, но если мы хотели бы обеспечить совместимость с драйверами внешних устройств и другими модулями ядра предыдущих версий ОС...
Из материала предыдущей главы легко понять, что код, рассчитанный на работу в однопоточной среде или среде кооперативной многозадачности, при переносе в многопоточную среду нуждается в значительной переработке, а нередко и в перепроектировании. Таким образом, сделать из монолитной (пусть даже модульной) системы микроядерную практически невозможно.
Следует учитывать, что требование поддержки многопроцессорных машин Или приложений реального времени часто предъявляется к разработчикам через много лет после того, как были приняты архитектурные решения. о этой ситуации разработчики часто не переходят на микроядерную архитектуру полностью, а создают архитектуру гибридную (или, если применить более эстетский термин, эклектичную).
Действительно, как говорилось ранее, в чистом микроядре взаимодействия Происходят асинхронно, а в чистом монолитном ядре — синхронно.
Если некоторые из взаимодействий происходят асинхронно (что например, в многопроцессорной машине), то мы можем сказать, что система частично микроядерная. Если же некоторые из взаимодействий обязательно синхронны, мы, наверное, вынуждены будем признать, что цаи система частично монолитная, как бы странно это ни звучало.
В зависимости от того, какого рода взаимодействия преобладают, мы може выстроить целый спектр более или менее монолитных (и, напротив, боле или менее микроядерных) архитектур. На практике, большинство современных ОС общего назначения имеют гибридную архитектуру, которая не является микроядерной, и в то же время не может быть классифицирована как монолитная. Многие из архитектур и, во всяком случае, многие из ключевых принципов взаимодействия между модулями современных операционных систем были разработаны еще до того, как появилось само слово "микроядро". При этом некоторые из этих взаимодействий имеют синхронный, а некоторые — особенно взаимодействие с драйверами внешних устройств — асинхронный характер.
Во многих современных ОС широко применяется взаимодействие драйверов с остальной системой посредством очередей запросов (или событий). Такое взаимодействие отчасти стирает различия между синхронным и полностью асинхронным межмодульным взаимодействием.

Классификация операционных систем Виртуальная память Реализация многозадачности
Системы безопасности Операционная система Linux Введение в компьютерные сети Принципы построения вычислительных систем Базовые технологии локальной сетиСредства анализа Процедуры и функции Pascal Язык запросов SQL Программирование на СИ Брандмауэры Протоколы TCP/IP Файловые системы Драйверы устройств