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

Монолитные системы и системы с микроядром

Не бывает монолитных программ, бывают плохо структурированные.

Реплика с семинара по ООП

Ходовая часть танка работает в экстремальных условиях и с трудом поддается модернизации.

Реплика в эхоконференции RU.WEAPON сети ФИДО

Исполняя системный вызов, пользовательская программа передает управление ядру. С понятием ядра – комплекса программ, исполняющихся в привилегированном (системном) режиме процессора, – мы уже сталкивались в разд. "Системы с базовой виртуальной адресацией" и Главе 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 и ряд других систем общего назначения более или менее успешно ее используют.

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

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