Разделы с фиксированными границами

Разбиение всего объема оперативной памяти на несколько разделов может осу­ществляться единовременно (в процессе генерации ОС). Пример разбиения памяти на несколько разделов приведен на рис. 1.6.

В каждом разделе в каждый момент времени может располагаться по одной программе (задаче). В этом случае по отношению к каждому разделу можно приме­нить все те методы создания программ, которые используются для однопрограммных систем. Возможно использование оверлейных структур, что позволяет создавать большие сложные программы и в то же время поддерживать коэффи­циент мультипрограммирования (под коэффициентом мультипрограммирова­ния понимают количество параллельно выполняемых программ) на должном уровне. Первые мультипрограммные ОС строились по этой схеме. Использова­лась эта схема и много лет спустя при создании недорогих вычислительных систем, ибо она является несложной и обеспечивает возможность параллельного выполнения программ. Иногда в некотором разделе размещалось по несколько небольших программ, которые постоянно в нем и находились. Такие программы назывались ОЗУ-резидентными или резидентными. Они же исполь­зуются и в современных встроенных системах; правда, для них характерно, что все прог­раммы являются резидентными и внешняя память во время работы вы­числительного оборудования не используется.

При небольшом объеме памяти и, следовательно, небольшом количестве раз­делов увеличить количество параллельно выполняемых приложений (особенно когда эти приложения интерактивны и во время своей работы они фактически не используют процессорное время, а в основном ожидают операций ввода/вы­вода) можно за счет своппинга (swapping). При своппинге задача может быть це­ликом выгружена на магнитный диск (перемещена во внешнюю память), а на ее место за­гружается либо более привилегированная, либо просто готовая к выпол­нению другая задача, находившаяся на диске в приостановленном состоянии. При своппинге из основной памяти во внешнюю (и обратно) перемещается вся программа, а не ее отдельная часть.

Серьезная проблема, которая возникает при организации мультипрограммного режима работы вычислительной системы, – это защита как самой ОС от ошибок и преднамеренного вмешательства задач в ее работу, так и самих задач друг от друга.

В самом деле, программа может обращаться к любым ячейкам в пределах своего виртуального адресного пространства. Если система отображения памяти не со­держит ошибок и в самой программе их тоже нет, то возникать ошибок при вы­полнении программы не должно. Однако в случае ошибок адресации, что не так уж и редко случается, исполняющаяся программа может начать «обработку» чу­жих данных или кодов с непредсказуемыми последствиями. Одной из простей­ших, но достаточно сильных мер является введение регистров защиты памяти. В эти регистры ОС заносит граничные значения области памяти раздела теку­щей исполняющейся задачи. При нарушении адресации возникает прерывание и управление передается супервизору ОС. Обращения к ОС за необходимыми сервисами осуществляются не напрямую, а через команды программных преры­ваний, что обеспечивает передачу управления только в предопределенные вход­ные точки кода ОС и в системном режиме работы процессора, при котором регистры защиты памяти игнорируются. Таким образом, выполнение функции защиты требует введения специальных аппаратных механизмов, используемых операционной системой.

Основным недостатком такого способа распределения памяти является наличие порой достаточно большого объема неиспользуемой памяти (см. рис. 1.6). Неис­пользуемая память может быть в каждом из разделов. Поскольку разделов не­сколько, то и неиспользуемых областей получается несколько, поэтому такие потери стали называть фрагментацией памяти. В отдельных разделах потери памяти могут быть очень значительными, однако использовать фрагменты сво­бодной памяти при таком способе распределения не представляется возможным. Желание разработчиков сократить столь значительные потери привело их к сле­дующим двум решениям:

1) выделять раздел ровно такого объема, который нужен под текущую задачу;

2) размещать задачу не в одной непрерывной области памяти, а в нескольких областях.