Вы находитесь на странице: 1из 25

1. Операционная система...................................................................................

2ст
1.1 ОС как расширенная машина ....................................................................................2ст
1.2 ОС как система управления ресурсами ....................................................................2ст
2. Управление процессами.................................................................................3ст
2.1 Процессы .................................................................................................3ст
2.2 Модель процесса .....................................................................................3ст
2.3 Создание процесса ..................................................................................3ст
2.4 Завершение процесса ..............................................................................5ст
2.5 Иерархия процессов ................................................................................6ст
2.6 Состояния процессов ..............................................................................6ст
2.7 Реализация процессов .............................................................................8ст
3. Управление памятью ......................................................................................8ст
3.1 Основное управление памятью ..............................................................9ст
3.2 Подкачка ................................................. .................................................9ст
3.3 Виртуальная память.................................................................................9ст
3.4 Алгоритмы замещения страниц ............................................................10ст
3.5 Исследования в области управления памятью ....................................11ст
4. Управление вводом-выводом........................................................................11ст
4.1 Физическая организация устройств ввода-вывода..................................................11ст
4.2 Организация программного обеспечения ввода-вывода........................................12ст
4.3 Обработка прерываний.................................................................................13ст
4.4 Драйверы устройств.....................................................................................13ст
5. Файловая система................................................. ........................................14ст
5.1 Имена файлов................................................. ............................................14ст
5.2 Типы файлов................................................. ..............................................15ст
5.3 Логическая организация файла......................................................................17ст
5.4 Физическая организация и адрес файла..........................................................18ст
5.5 Права доступа к файлу..................................................................................20ст
6. Интерфейс пользователя...............................................................................21ст
6.1. Командный язык и командный процессор.....................................................21ст
6.2. Командные файлы и язык процедур..............................................................22ст
6.3. Проблема идентификации адресата..............................................................23ст
6.4. WIMP-интерфейс........................................................................................24ст
1. Определение операционной системы

Операционная система в наибольшей степени определяет облик всей вычислительной


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

1.1 ОС как расширенная машина


Использование большинства компьютеров на уровне машинного языка затруднительно,
особенно это касается ввода-вывода. Например, для организации чтения блока данных с
гибкого диска программист может использовать 16 различных команд, каждая из которых
требует 13 параметров, таких как номер блока на диске, номер сектора на дорожке и т. п.
Когда выполнение операции с диском завершается, контроллер возвращает 23 значения,
отражающих наличие и типы ошибок, которые, очевидно, надо анализировать. Даже если не
входить в курс реальных проблем программирования ввода-вывода, ясно, что среди
программистов нашлось бы не много желающих непосредственно заниматься
программированием этих операций. При работе с диском программисту-пользователю
достаточно представлять его в виде некоторого набора файлов, каждый из которых имеет
имя. Работа с файлом заключается в его открытии, выполнении чтения или записи, а затем в
закрытии файла. Вопросы подобные таким, как следует ли при записи использовать
усовершенствованную частотную модуляцию или в каком состоянии сейчас находится
двигатель механизма перемещения считывающих головок, не должны волновать
пользователя. Программа, которая скрывает от программиста все реалии аппаратуры и
предоставляет возможность простого, удобного просмотра указанных файлов, чтения или
записи - это, конечно, операционная система. Точно также, как ОС ограждает программистов
от аппаратуры дискового накопителя и предоставляет ему простой файловый интерфейс,
операционная система берет на себя все малоприятные дела, связанные с обработкой
прерываний, управлением таймерами и оперативной памятью, а также другие
низкоуровневые проблемы. В каждом случае та абстрактная, воображаемая машина, с
которой, благодаря операционной системе, теперь может иметь дело пользователь, гораздо
проще и удобнее в обращении, чем реальная аппаратура, лежащая в основе этой абстрактной
машины.
С этой точки зрения функцией ОС является предоставление пользователю некоторой
расширенной или виртуальной машины, которую легче программировать и с которой легче
работать, чем непосредственно с аппаратурой, составляющей реальную машину.

1.2 ОС как система управления ресурсами


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

2. Управление процессами

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

2.2 Модель процесса


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

2.3 Создание процесса


Операционной системе необходим способ, позволяющий удостовериться в наличии всех
необходимых процессов. В простейших системах, а также системах, разработанных для
выполнения одного-единственного приложения (например, контроллер микроволновой печи),
можно реализовать такую ситуацию, в которой все процессы, которые когда-либо могут

3
понадобиться, присутствуют в системе при ее загрузке. В универсальных системах
необходим способ создания и прерывания процессов по мере необходимости. В этом разделе
мы рассмотрим некоторые из возможных способов решения этой проблемы. Ниже
перечислены четыре основных события, приводящие к созданию процессов.
Инициализация системы.
Выполнение изданного работающим процессом системного запроса на создание
процесса.
Запрос пользователя на создание процесса.
Инициирование пакетного задания.
Обычно при загрузке операционной системы создаются несколько процессов. Некоторые
из них являются высокоприоритетными процессами, то есть обеспечивающими
взаимодействие с пользователем и выполняющими заданную работу. Остальные процессы
являются фоновыми, они не связаны с конкретными пользователями, но выполняют особые
функции. Например, один фоновый процесс может быть предназначен для обработки
приходящей на компьютер почты, активизируясь только по мере появления писем. Другой
фоновый процесс может обрабатывать запросы к web-страницам, расположенным на
компьютере, и активизироваться для обслуживания полученного запроса. Фоновые
процессы, связанные с электронной почтой, web-страницами, новостями, выводом на печать
и т. п., называются демонами. В больших системах насчитываются десятки демонов. В UNIX
для вывода списка запущенных процессов используется программа ps. В Windows 95/98/Ме
достаточно нажать CTRL-ALT-DEL, а в Windows 2000 можно воспользоваться диспетчером
задач, вызываемым этой же комбинацией трех клавиш.
Процессы могут создаваться не только в момент загрузки системы, но и позже. Например,
новый процесс (или несколько) может быть создан по просьбе текущего процесса. Создание
новых процессов особенно полезно в тех случаях, когда выполняемую задачу проще всего
сформировать как набор связанных, но тем не менее независимых взаимодействующих
процессов. Если необходимо организовать выборку большого количества данных из сети для
дальнейшей обработки, удобно создать один процесс для выборки данных и размещения их в
совместно используемом буфере, в то время как второй процесс будет считывать данные из
буфера и обрабатывать их. Эта схема даже ускорит обработку данных, если каждый процесс
запустить на отдельном процессоре в случае многопроцессорной системы.
В интерактивных системах пользователь может запустить программу, набрав на
клавиатуре команду или дважды щелкнув на значке программы. В обоих случаях результатом
будет создание нового процесса и запуск в нем программы. Когда на UNIX работает X
Windows, новый процесс получает то окно, в котором был запущен. В Microsoft Windows
процесс не имеет собственного окна при запуске, но он может (и должен) создать одно или
несколько окон. В обеих системах пользователь может одновременно открыть несколько
окон, каждому из которых соответствует свой процесс. Пользователь может переключаться
между окнами с помощью мыши и взаимодействовать с процессом, например, вводя данные
по мере необходимости.
Последнее событие, приводящее к созданию нового процесса, связано с системами
пакетной обработки на больших компьютерах. Пользователи посылают пакетное задание
(возможно, с использованием удаленного доступа), а операционная система создает новый
процесс и запускает следующее задание из очереди в тот момент, когда освобождаются
необходимые ресурсы.
С технической точки зрения во всех перечисленных случаях новый процесс формируется
одинаково: текущий процесс выполняет системный запрос на создание нового процесса. В
роли текущего процесса может выступать процесс, запущенный пользователем, системный
процесс, инициированный клавиатурой или мышью, а также процесс, управляющий
пакетами. В любом случае этот процесс всего лишь выполняет системный запрос и создает

4
новый процесс. Системный запрос заставляет операционную систему создать новый процесс,
а также прямо или косвенно содержит информацию о программе, которую нужно запустить в
этом процессе.

2.4 Завершение процесса


После того как процесс создан, он начинает выполнять свою работу. Но ничто не длится
вечно, даже процесс - рано или поздно он завершится, чаще всего благодаря одному из
следующих событий:
Обычный выход (преднамеренно).
Выход по ошибке (преднамеренно).
Выход по неисправимой ошибке (непреднамеренно).
Уничтожение другим процессом (непреднамеренно).
В основном процессы завершаются по мере выполнения своей работы. После окончания
компиляции программы компилятор выполняет системный запрос, чтобы сообщить
операционной системе об окончании работы. В UNIX этот системный запрос - exit, а в
Windows - ExitProcess. Программы, рассчитанные на работу с экраном, также поддерживают
преднамеренное завершение. В текстовых редакторах, браузерах и других программах такого
типа обычно есть кнопка или пункт меню, щелкнув на котором можно удалить все
временные файлы, открытые процессом, и затем завершить процесс.
Второй причиной завершения процесса может стать неустранимая ошибка. Например,
если пользователь набрал на клавиатуре команду
cc foo.c
для компиляции программы foo.c, а соответствующего файла не существует, компилятор
просто закончит работу. Интерактивные процессы, рассчитанные на работу с экраном,
обычно не завершают работу при получении неверных параметров, вместо этого выводя на
экран диалоговое окно и прося пользователя ввести правильные параметры.
Третьей причиной завершения процесса является ошибка, вызванная самим процессом,
чаще всего связанная с ошибкой в программе. В качестве примера можно привести
выполнение недопустимой команды, обращение к несуществующей области памяти и
деление на ноль. В некоторых системах (например, в UNIX) процесс может информировать
операционную систему о том, что он сам обработает некоторые ошибки, и в этом случае
процессу посылается сигнал (процесс прерывается, а не завершается) при появлении
ошибки.
Четвертой причиной завершения процесса может служить выполнение другим процессом
системного запроса на уничтожение процесса. В UNIX такой системный запрос - kill, а
соответствующая функция Win32 - TerminateProcess. В обоих случаях "киллер" должен
обладать соответствующими полномочиями по отношению к "убиваемому" процессу. В
некоторых системах при завершении процесса (преднамеренно или нет) все процессы,
созданные процессом, также завершаются. Впрочем, это не относится ни к UNIX, ни к
Windows.

2.5 Иерархия процессов


В некоторых системах родительский и дочерний процессы остаются связанными между
собой определенным образом. Дочерний процесс также может, в свою очередь, создавать
процессы, формируя иерархию процессов. Следует отметить, что в отличие от животного
мира у процесса может быть лишь один родитель и сколько угодно "детей".
В UNIX процесс, все его "дети" и дальнейшие потомки образуют группу процессов.
Сигнал, посылаемый пользователем с клавиатуры, доставляется всем членам группы,

5
взаимодействующим с клавиатурой в данный момент (обычно это все активные процессы,
созданные в текущем окне). Каждый из процессов может перехватить сигнал, игнорировать
его или выполнить другое действие, предусмотренное по умолчанию.

Рассмотрим в качестве еще одного примера иерархии процессов инициализацию UNIX


при запуске. В образе загрузки присутствует специальный процесс init. При запуске этот
процесс считывает файл, в котором находится информация о количестве терминалов. Затем
процесс разветвляется таким образом, чтобы каждому терминалу соответствовал один
процесс. Процессы ждут, пока какой-нибудь пользователь не войдет в систему. Если пароль
правильный, процесс входа в систему запускает оболочку для обработки команд
пользователя, которые, в свою очередь, могут запускать процессы. Таким образом, все
процессы в системе принадлежат к единому дереву, начинающемуся с процесса init.
Напротив, в Windows не существует понятия иерархии процессов, и все процессы
равноправны. Единственное, в чем проявляется что-то вроде иерархии процессов - создание
процесса, в котором родительский процесс получает специальный маркер (так называемый
дескриптор), позволяющий контролировать дочерний процесс. Но маркер можно передать
другому процессу, нарушая иерархию. В UNIX это невозможно.

2.6 Состояния процессов


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

На рис. 2.2 представлена диаграмма состояний, показывающая три возможных состояния


процесса:
Работающий (в этот конкретный момент использующий процессор).
Готовый к работе (процесс временно приостановлен, чтобы позволить выполняться
другому процессу).
Заблокированный (процесс не может быть запущен прежде, чем произойдет некое
внешнее событие).
Процесс блокируется, ожидая входных данных
Планировщик выбирает другой процесс
Планировщик выбирает этот процесс
Доступны входные данные
Рис. 2.2. Процесс может находиться в рабочем, готовом и заблокированном состоянии.
Стрелками показаны возможные переходы между состояниями
С точки зрения логики первые два состояния одинаковы. В обоих случаях процесс может
быть запущен, только во втором случае недоступен процессор. Третье состояние отличается
тем, что запустить процесс невозможно, независимо от загруженности процессора.
Как показано на рис. 2.2, между этими тремя состояниями возможны четыре перехода.
Переход 1 происходит, когда процесс обнаруживает, что продолжение работы невозможно. В
некоторых системах процесс должен выполнить системный запрос, например block или
pause, чтобы оказаться в заблокированном состоянии. В других системах, как в UNIX,

6
процесс автоматически блокируется, если при считывании из канала или специального файла
(предположим, терминала) входные данные не были обнаружены.
Переходы 2 и 3 вызываются частью операционной системы, называемой планировщиком
процессов, так что сами процессы даже не знают о существовании этих переходов. Переход 2
происходит, если планировщик решил, что пора предоставить процессор следующему
процессу. Переход 3 происходит, когда все остальные процессы уже исчерпали свое
процессорное время, и процессор снова возвращается к первому процессу. Вопрос
планирования (когда следует запустить очередной процесс и на какое время) сам по себе
достаточно важен, и мы вернемся к нему позже в этой главе. Было разработано множество
алгоритмов с целью сбалансировать требования эффективности для системы в целом и для
каждого процесса в отдельности. Мы также рассмотрим некоторые из них ниже в этой главе.
Переход 4 происходит с появлением внешнего события, ожидавшегося процессом
(например, прибытие входных данных). Если в этот момент не запущен какой-либо другой
процесс, то срабатывает переход 3, и процесс запускается. В противном случае процессу
придется некоторое время находиться в состоянии готовности, пока не освободится
процессор.
Модель процессов упрощает представление о внутреннем поведении системы. Некоторые
процессы запускают программы, выполняющие команды, введенные с клавиатуры
пользователем. Другие процессы являются частью системы и обрабатывают такие задачи, как
выполнение запросов файловой службы, управление запуском диска или магнитного
накопителя. В случае дискового прерывания система останавливает текущий процесс и
запускает дисковый процесс, который был заблокирован в ожидании этого прерывания.
Вместо прерываний мы можем представлять себе дисковые процессы, процессы
пользователя, терминала и т. п., блокирующиеся на время ожидания событий. Когда событие
произошло (информация прочитана с диска или клавиатуры), блокировка снимается и
процесс может быть запущен.
Рассмотренный подход описывается моделью, представленной на рис. 2.3. Нижний
уровень операционной системы - это планировщик, на верхних уровнях расположено
множество процессов. Вся обработка прерываний и детали, связанные с остановкой и
запуском процессов, спрятаны в том, что мы назвали планировщиком, являющимся, по сути,
совсем небольшой программой. Вся остальная часть операционной системы удобно
структурирована в виде набора процессов. Очень немногие существующие системы
структурированы столь удобно.

Рис. 2.3. Нижний уровень операционной системы отвечает за прерывания и


планирование.
Выше расположены последовательные процессы

2.7 Реализация процессов


Для реализации модели процессов операционная система содержит таблицу (массив
структур), называемую таблицей процессов, с одним элементом для каждого процесса.
(Некоторые авторы называют эти элементы блоками управления процессом.) Элемент
таблицы содержит информацию о состоянии процесса, счетчике команд, указателе стека,
распределении памяти, состоянии открытых файлов, об использовании и распределении
ресурсов, а также всю остальную информацию, которую необходимо сохранять при

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

3. Управление памятью

В каждом компьютере есть оперативная память, используемая для хранения


выполняющихся программ. В очень простых операционных системах в конкретный момент
времени в памяти может находиться только одна программа. Для запуска второй программы
сначала нужно удалить из памяти первую и загрузить на ее место вторую. Более изощренные
системы позволяют одновременно находиться в памяти нескольким программам. Для того
чтобы они не мешали друг другу (и операционной системе), необходим некий защитный
механизм. Хотя этот механизм располагается в аппаратуре, он управляется операционной
системой.
Вышеизложенная точка зрения имеет отношение к управлению оперативной памятью
компьютера и к ее защите. Другой, но не менее важный, связанный с памятью вопрос - это
управление адресным пространством процессов. Обычно под каждый процесс отводится
некоторый набор адресов, которые он может использовать, чаще всего начинающийся с 0 и
продолжающийся до некого максимума. В простейшем случае максимальная величина
адресного пространства для процесса меньше основной памяти. Тогда процесс может
заполнить свое адресное пространство, и памяти хватит на то, чтобы содержать его целиком.
Однако на многих компьютерах адресация 32- или 64-разрядная, что дает для
пространства адресов 232 и 264 байтов соответственно. Что произойдет, если адресное
пространство процесса окажется больше, чем оперативная память компьютера, и процесс
захочет использовать его целиком? На первых компьютерах подобным процессам просто не
везло. В наши дни существует метод, называемый виртуальной памятью, при котором

8
операционная система держит часть адресов в оперативной памяти, а часть на диске и меняет
их местами при необходимости.

3.1 Основное управление памятью


Системы управления памятью можно разделить на два класса: перемещающие процессы
между оперативной памятью и диском во время их выполнения (то есть осуществляющие
подкачку процессов целиком (swapping) или использующие страничную подкачку (paging)) и
те, которые этого не делают. Второй вариант проще, поэтому начнем с него, а два
упомянутых выше вида подкачки мы изучим позже в этой же главе. Читая главу 4, следует
помнить, что обычный и постраничный варианты подкачки в значительной степени являются
искусственными процессами, вызванными отсутствием достаточного количества
оперативной памяти для одновременного хранения всех программ. Если же когда-нибудь
оперативная память настолько увеличится в размерах, что ее будет достаточно, аргументы в
пользу той или иной схемы управления памятью могут стать устаревшими.
С другой стороны, выше уже упоминалось, что программное обеспечение растет еще
быстрее, чем память; поэтому вполне возможно, что потребность в рациональном и
эффективном управлении памятью будет существовать всегда. В 80-е годы многие
университеты использовали системы разделения времени для работы десятков (более-менее
довольных) пользователей на машинах VAX с объемом памяти 4 Мбайт. Сейчас компания
Microsoft рекомендует для индивидуальной работы в системе Windows 2000 устанавливать на
компьютер, по меньшей мере, 64 Мбайт оперативной памяти. Дальнейшее развитие в
сторону мультимедийных систем накладывает еще большие требования на память. Таким
образом, весьма вероятно, что качество управления этой частью компьтера будет актуальным
по крайней мере в течение следующего десятилетия.

3.2 Подкачка
Организация памяти в виде фиксированных разделов проста и эффективна для работы с
пакетными системами. Каждое задание после того, как доходит до начала очереди,
загружается в раздел памяти и остается там до своего завершения. До тех пор пока в памяти
может храниться достаточное количество задач для обеспечения постоянной занятости
центрального процессора, нет причин что-либо усложнять.
Но совершенно другая ситуация сложилась с системами разделения времени или
персональными компьютерами, ориентированными на работу с графикой. Оперативной
памяти иногда оказывается недостаточно для того, чтобы вместить все текущие активные
процессы, и тогда избыток процессов приходится хранить на диске, а для обработки
динамически переносить их в память.
Существуют два основных подхода к управлению памятью, зависящие (отчасти) от
доступного аппаратного обеспечения. Самая простая стратегия, называемая свопингом
(swapping) или обычной подкачкой, заключается в том, что каждый процесс полностью
переносится в память, работает некоторое время и затем целиком возвращается на диск.
Другая стратегия, носящая название виртуальной памяти, позволяет программам работать
даже тогда, когда они только частично находятся в оперативной памяти.

3.3 Виртуальная память


Уже достаточно давно люди впервые столкнулись с проблемой размещения программ,
оказавшихся слишком большими и поэтому не помещавшихся в доступной физической
памяти. Обычно принималось решение о разделении программы на части, называемые
оверлеями (overlays). Оверлей 0 обычно запускался первым. После окончания своего
выполнения он вызывал следующий оверлей. Некоторые оверлейные системы были очень

9
сложными, позволяющими одновременно находиться в памяти нескольким оверлеям.
Оверлеи хранились на диске и по мере необходимости динамически перемещались между
памятью и диском средствами операционной системы.
Несмотря на то что фактическая работа по загрузке оверлеев с диска и выгрузке на диск
выполнялась системой, делить программы на части должен был программист. Разбиение
больших программ на маленькие модули поглощало много времени и было не слишком
интересным занятием. Однако такая ситуация продолжалась недолго, так как вскоре кто-то
придумал способ поручить всю эту работу компьютеру.
Разработанный метод известен как виртуальная память [122]. Основная идея виртуальной
памяти заключается в том, что объединенный размер программы, данных и стека может
превысить количество доступной физической памяти. Операционная система хранит части
программы, использующиеся в настоящий момент, в оперативной памяти, остальные - на
диске. Например, программа размером 16 Мбайт сможет работать на машине с 4 Мбайт
памяти, если тщательно продумать, какие 4 Мбайт должны храниться в памяти в каждый
момент времени. При этом части программы, находящиеся на диске и в памяти, будут
меняться местами по мере необходимости.
Виртуальная память может также работать в многозадачной системе при одновременно
находящихся в памяти частях многих программ. Когда программа ждет перемещения в
память очередной ее части, она находится в состоянии ожидания ввода-вывода и не может
работать, поэтому центральный процессор может быть отдан другому процессу тем же
самым способом, как в любой другой многозадачной системе.

3.4 Алгоритмы замещения страниц


Когда происходит страничное прерывание, операционная система должна выбрать
страницу для удаления из памяти, чтобы освободить место для страницы, которую нужно
перенести в память. Если удаляемая страница была изменена за время своего присутствия в
памяти, ее необходимо переписать на диск, чтобы обновить копию, хранящуюся там. Однако
если страница не была модифицирована (например, она содержит текст программы), копия
на диске уже является самой новой и ее не надо переписывать. Тогда страница, которую
нужно прочитать, просто считывается поверх выгружаемой страницы.
Хотя в принципе можно при каждом страничном прерывании выбирать случайную
страницу для удаления из памяти, производительность системы заметно повышается, когда
предпочтение отдается редко используемой странице. Если выгружается страница,
обращения к которой происходят часто, велика вероятность, что вскоре опять потребуется ее
возврат в память, что даст в результате дополнительные издержки. Теме разработки
алгоритмов замены страницы было посвящено много работ, как теоретических, так и
экспериментальных. Ниже мы опишем некоторые из наиболее важных алгоритмов.
Следует отметить, что проблема "страничного обмена" также встает и в других областях
конструирования компьютеров. Например, у большинства компьютеров есть один или
несколько кэшей, состоящих из используемых в последнее время 32-байтовых или 64-
байтовых блоков памяти. Когда кэш заполнен, необходимо выбрать некоторые блоки для
удаления. Эта проблема практически аналогична замещению страниц лишь с одной
разницей, заключающейся в меньшем масштабе времени (операция должна быть выполнена
за несколько наносекунд, а не миллисекунд, как для замены страниц). Причиной для более
короткого промежутка времени является то, что неудачный поиск блока в кэше
обрабатывается из основной памяти, в которой не тратится время на поиск нужного
цилиндра диска и нет задержки из-за его вращения.
Второй пример встречается на web-серверах. Сервер может хранить определенное
количество часто используемых web-страниц в своей кэш-памяти. Однако когда кэш-память
заполняется целиком и происходит обращение к новой странице, должно приниматься

10
решение о том, какую из страниц выгружать. Здесь применимы те же рассуждения, что и для
страниц в виртуальной памяти, с той разницей, что web-страницы никогда не изменяются в
кэше, поэтому для них всегда есть свежая копия на диске. В системе виртуальной памяти
страницы в оперативной памяти могут быть "чистыми" или "грязными".

3.5 Исследования в области управления памятью


Управление памятью, особенно алгоритмы страничной подкачки, когда-то было
плодотворной областью для исследований, но, кажется, большая часть этих изысканий (по
крайней мере, для универсальных систем) сейчас отмерла. Реальные системы чаще всего
используют некоторые разновидности алгоритма "часы", потому что он прост в реализации и
относительно эффективен. Есть, правда, одно свежее исключение - доработка системы
виртуальной памяти 4.4 BSD [79].
Тем не менее до сих пор проводятся исследования, касающиеся страничной организации
памяти в универсальных и новейших видах систем. Некоторые из этих работ направлены на
то, чтобы позволить пользовательским процессам обрабатывать свои собственные
страничные прерывания и осуществлять свое собственное управление памятью, возможно,
некоторым специальным способом [110]. Одной из областей, где могут понадобиться
приложения, осуществляющие собственную организацию страничной структуры, являются
мультимедийные системы, поэтому некоторые исследования на эту тему рассматривались в
[142]. Другой областью, которая имеет некоторые особенные требования, являются
портативные персональные средства связи ([3, 354]). И последняя область - это системы с 64-
разрядным адресным пространством, разделяемым множеством процессов [321].

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

4.1 Физическая организация устройств ввода-вывода


Устройства ввода-вывода делятся на два типа: блок-ориентированные устройства и байт-
ориентированные устройства. Блок-ориентированные устройства хранят информацию в
блоках фиксированного размера, каждый из которых имеет свой собственный адрес. Самое
распространенное блок-ориентированное устройство - диск. Байт-ориентированные
устройства не адресуемы и не позволяют производить операцию поиска, они генерируют или
потребляют последовательность байтов. Примерами являются терминалы, строчные
принтеры, сетевые адаптеры. Однако некоторые внешние устройства не относятся ни к
одному классу, например, часы, которые, с одной стороны, не адресуемы, а с другой стороны,
не порождают потока байтов. Это устройство только выдает сигнал прерывания в некоторые
моменты времени.
Внешнее устройство обычно состоит из механического и электронного компонента.
Электронный компонент называется контроллером устройства или адаптером. Механический
компонент представляет собственно устройство. Некоторые контроллеры могут управлять
несколькими устройствами. Если интерфейс между контроллером и устройством
стандартизован, то независимые производители могут выпускать совместимые как
контроллеры, так и устройства.
Операционная система обычно имеет дело не с устройством, а с контроллером.
Контроллер, как правило, выполняет простые функции, например, преобразует поток бит в

11
блоки, состоящие из байт, и осуществляют контроль и исправление ошибок. Каждый
контроллер имеет несколько регистров, которые используются для взаимодействия с
центральным процессором. В некоторых компьютерах эти регистры являются частью
физического адресного пространства. В таких компьютерах нет специальных операций
ввода-вывода. В других компьютерах адреса регистров ввода-вывода, называемых часто
портами, образуют собственное адресное пространство за счет введения специальных
операций ввода-вывода (например, команд IN и OUT в процессорах i86).
ОС выполняет ввод-вывод, записывая команды в регистры контроллера. Например,
контроллер гибкого диска IBM PC принимает 15 команд, таких как READ, WRITE, SEEK,
FORMAT и т.д. Когда команда принята, процессор оставляет контроллер и занимается другой
работой. При завершении команды контроллер организует прерывание для того, чтобы
передать управление процессором операционной системе, которая должна проверить
результаты операции. Процессор получает результаты и статус устройства, читая
информацию из регистров контроллера.

4.2 Организация программного обеспечения ввода-вывода


Основная идея организации программного обеспечения ввода-вывода состоит в
разбиении его на несколько уровней, причем нижние уровни обеспечивают экранирование
особенностей аппаратуры от верхних, а те, в свою очередь, обеспечивают удобный
интерфейс для пользователей.
Ключевым принципом является независимость от устройств. Вид программы не должен
зависеть от того, читает ли она данные с гибкого диска или с жесткого диска.
Очень близкой к идее независимости от устройств является идея единообразного
именования, то есть для именования устройств должны быть приняты единые правила.
Другим важным вопросом для программного обеспечения ввода-вывода является
обработка ошибок. Вообще говоря, ошибки следует обрабатывать как можно ближе к
аппаратуре. Если контроллер обнаруживает ошибку чтения, то он должен попытаться ее
скорректировать. Если же это ему не удается, то исправлением ошибок должен заняться
драйвер устройства. Многие ошибки могут исчезать при повторных попытках выполнения
операций ввода-вывода, например, ошибки, вызванные наличием пылинок на головках
чтения или на диске. И только если нижний уровень не может справиться с ошибкой, он
сообщает об ошибке верхнему уровню.
Еще один ключевой вопрос - это использование блокирующих (синхронных) и
неблокирующих (асинхронных) передач. Большинство операций физического ввода-вывода
выполняется асинхронно - процессор начинает передачу и переходит на другую работу, пока
не наступает прерывание. Пользовательские программы намного легче писать, если
операции ввода-вывода блокирующие - после команды READ программа автоматически
приостанавливается до тех пор, пока данные не попадут в буфер программы. ОС выполняет
операции ввода-вывода асинхронно, но представляет их для пользовательских программ в
синхронной форме.
Последняя проблема состоит в том, что одни устройства являются разделяемыми, а
другие - выделенными. Диски - это разделяемые устройства, так как одновременный доступ
нескольких пользователей к диску не представляет собой проблему. Принтеры - это
выделенные устройства, потому что нельзя смешивать строчки, печатаемые различными
пользователями. Наличие выделенных устройств создает для операционной системы
некоторые проблемы.
Для решения поставленных проблем целесообразно разделить программное обеспечение
ввода-вывода на четыре слоя (рисунок 2.30):
Обработка прерываний,
Драйверы устройств,
12
Независимый от устройств слой операционной системы,
Пользовательский слой программного обеспечения.

Рис. 2.30. Многоуровневая организация подсистемы ввода-вывода

4.3 Обработка прерываний


Прерывания должны быть скрыты как можно глубже в недрах операционной системы,
чтобы как можно меньшая часть ОС имела с ними дело. Наилучший способ состоит в
разрешении процессу, инициировавшему операцию ввода-вывода, блокировать себя до
завершения операции и наступления прерывания. Процесс может блокировать себя,
используя, например, вызов DOWN для семафора, или вызов WAIT для переменной условия,
или вызов RECEIVE для ожидания сообщения. При наступлении прерывания процедура
обработки прерывания выполняет разблокирование процесса, инициировавшего операцию
ввода-вывода, используя вызовы UP, SIGNAL или посылая процессу сообщение. В любом
случае эффект от прерывания будет состоять в том, что ранее заблокированный процесс
теперь продолжит свое выполнение.

4.4 Драйверы устройств


Весь зависимый от устройства код помещается в драйвер устройства. Каждый драйвер
управляет устройствами одного типа или, может быть, одного класса.
В операционной системе только драйвер устройства знает о конкретных особенностях
какого-либо устройства. Например, только драйвер диска имеет дело с дорожками,
секторами, цилиндрами, временем установления головки и другими факторами,
обеспечивающими правильную работу диска.
Драйвер устройства принимает запрос от устройств программного слоя и решает, как его
выполнить. Типичным запросом является чтение n блоков данных. Если драйвер был

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

5. Файловая система
Файловая система - это часть операционной системы, назначение которой состоит в том,
чтобы обеспечить пользователю удобный интерфейс при работе с данными, хранящимися на
диске, и обеспечить совместное использование файлов несколькими пользователями и
процессами.
В широком смысле понятие "файловая система" включает:
совокупность всех файлов на диске,
наборы структур данных, используемых для управления файлами, такие, например, как
каталоги файлов, дескрипторы файлов, таблицы распределения свободного и занятого
пространства на диске,
комплекс системных программных средств, реализующих управление файлами, в
частности: создание, уничтожение, чтение, запись, именование, поиск и другие операции над
файлами.

5.1 Имена файлов


Файлы идентифицируются именами. Пользователи дают файлам символьные имена, при
этом учитываются ограничения ОС как на используемые символы, так и на длину имени. До
недавнего времени эти границы были весьма узкими. Так в популярной файловой системе
FAT длина имен ограничивается известной схемой 8.3 (8 символов - собственно имя, 3
символа - расширение имени), а в ОС UNIX System V имя не может содержать более 14
символов. Однако пользователю гораздо удобнее работать с длинными именами, поскольку
они позволяют дать файлу действительно мнемоническое название, по которому даже через
достаточно большой промежуток времени можно будет вспомнить, что содержит этот файл.
Поэтому современные файловые системы, как правило, поддерживают длинные символьные
имена файлов. Например, Windows NT в своей новой файловой системе NTFS устанавливает,
что имя файла может содержать до 255 символов, не считая завершающего нулевого символа.
При переходе к длинным именам возникает проблема совместимости с ранее созданными
приложениями, использующими короткие имена. Чтобы приложения могли обращаться к
файлам в соответствии с принятыми ранее соглашениями, файловая система должна уметь
предоставлять эквивалентные короткие имена (псевдонимы) файлам, имеющим длинные
имена. Таким образом, одной из важных задач становится проблема генерации
соответствующих коротких имен.

14
Длинные имена поддерживаются не только новыми файловыми системами, но и новыми
версиями хорошо известных файловых систем. Например, в ОС Windows 95 используется
файловая система VFAT, представляющая собой существенно измененный вариант FAT.
Среди многих других усовершенствований одним из главных достоинств VFAT является
поддержка длинных имен. Кроме проблемы генерации эквивалентных коротких имен, при
реализации нового варианта FAT важной задачей была задача хранения длинных имен при
условии, что принципиально метод хранения и структура данных на диске не должны были
измениться.
Обычно разные файлы могут иметь одинаковые символьные имена. В этом случае файл
однозначно идентифицируется так называемым составным именем, представляющем собой
последовательность символьных имен каталогов. В некоторых системах одному и тому же
файлу не может быть дано несколько разных имен, а в других такое ограничение отсутствует.
В последнем случае операционная система присваивает файлу дополнительно уникальное
имя, так, чтобы можно было установить взаимно-однозначное соответствие между файлом и
его уникальным именем. Уникальное имя представляет собой числовой идентификатор и
используется программами операционной системы. Примером такого уникального имени
файла является номер индексного дескриптора в системе UNIX.

5.2 Типы файлов


Файлы бывают разных типов: обычные файлы, специальные файлы, файлы-каталоги.
Обычные файлы в свою очередь подразделяются на текстовые и двоичные. Текстовые
файлы состоят из строк символов, представленных в ASCII-коде. Это могут быть документы,
исходные тексты программ и т.п. Текстовые файлы можно прочитать на экране и распечатать
на принтере. Двоичные файлы не используют ASCII-коды, они часто имеют сложную
внутреннюю структуру, например, объектный код программы или архивный файл. Все
операционные системы должны уметь распознавать хотя бы один тип файлов - их
собственные исполняемые файлы.
Специальные файлы - это файлы, ассоциированные с устройствами ввода-вывода,
которые позволяют пользователю выполнять операции ввода-вывода, используя обычные
команды записи в файл или чтения из файла. Эти команды обрабатываются вначале
программами файловой системы, а затем на некотором этапе выполнения запроса
преобразуются ОС в команды управления соответствующим устройством. Специальные
файлы, так же как и устройства ввода-вывода, делятся на блок-ориентированные и байт-
ориентированные.
Каталог - это, с одной стороны, группа файлов, объединенных пользователем исходя из
некоторых соображений (например, файлы, содержащие программы игр, или файлы,
составляющие один программный пакет), а с другой стороны - это файл, содержащий
системную информацию о группе файлов, его составляющих. В каталоге содержится список
файлов, входящих в него, и устанавливается соответствие между файлами и их
характеристиками (атрибутами).
В разных файловых системах могут использоваться в качестве атрибутов разные
характеристики, например:
информация о разрешенном доступе,
пароль для доступа к файлу,
владелец файла,
создатель файла,
признак "только для чтения",
признак "скрытый файл",
признак "системный файл",

15
признак "архивный файл",
признак "двоичный/символьный",
признак "временный" (удалить после завершения процесса),
признак блокировки,
длина записи,
указатель на ключевое поле в записи,
длина ключа,
времена создания, последнего доступа и последнего изменения,
текущий размер файла,
максимальный размер файла.
Каталоги могут непосредственно содержать значения характеристик файлов, как это
сделано в файловой системе MS-DOS, или ссылаться на таблицы, содержащие эти
характеристики, как это реализовано в ОС UNIX (рисунок 2.31). Каталоги могут
образовывать иерархическую структуру за счет того, что каталог более низкого уровня может
входить в каталог более высокого уровня (рисунок 2.32).

Рис. 2.31. Структура каталогов: а - структура записи каталога MS-DOS (32 байта);
б - структура записи каталога ОС UNIX

Иерархия каталогов может быть деревом или сетью. Каталоги образуют дерево, если
файлу разрешено входить только в один каталог, и сеть - если файл может входить сразу в
несколько каталогов. В MS-DOS каталоги образуют древовидную структуру, а в UNIX'е -
сетевую. Как и любой другой файл, каталог имеет символьное имя и однозначно
идентифицируется составным именем, содержащим цепочку символьных имен всех
каталогов, через которые проходит путь от корня до данного каталога.

16
Рис. 2.32. Логическая организация файловой системы
а - одноуровневая; б - иерархическая (дерево); в - иерархическая (сеть)

5.3 Логическая организация файла


Программист имеет дело с логической организацией файла, представляя файл в виде
определенным образом организованных логических записей. Логическая запись - это
наименьший элемент данных, которым может оперировать программист при обмене с
внешним устройством. Даже если физический обмен с устройством осуществляется
большими единицами, операционная система обеспечивает программисту доступ к
отдельной логической записи. На рисунке 2.33 показаны несколько схем логической
организации файла. Записи могут быть фиксированной длины или переменной длины.
Записи могут быть расположены в файле последовательно (последовательная организация)
или в более сложном порядке, с использованием так называемых индексных таблиц,
позволяющих обеспечить быстрый доступ к отдельной логической записи (индексно-
последовательная организация). Для идентификации записи может быть использовано
специальное поле записи, называемое ключом. В файловых системах ОС UNIX и MS-DOS
файл имеет простейшую логическую структуру - последовательность однобайтовых записей.

17
Рис. 2.33. Способы логической организации файлов

5.4 Физическая организация и адрес файла


Физическая организация файла описывает правила расположения файла на устройстве
внешней памяти, в частности на диске. Файл состоит из физических записей - блоков. Блок -
наименьшая единица данных, которой внешнее устройство обменивается с оперативной
памятью. Непрерывное размещение - простейший вариант физической организации (рисунок
2.34,а), при котором файлу предоставляется последовательность блоков диска, образующих
единый сплошной участок дисковой памяти. Для задания адреса файла в этом случае
достаточно указать только номер начального блока. Другое достоинство этого метода -
простота. Но имеются и два существенных недостатка. Во-первых, во время создания файла
заранее не известна его длина, а значит не известно, сколько памяти надо зарезервировать
для этого файла, во-вторых, при таком порядке размещения неизбежно возникает
фрагментация, и пространство на диске используется не эффективно, так как отдельные
участки маленького размера (минимально 1 блок) могут остаться не используемыми.
Следующий способ физической организации - размещение в виде связанного списка
блоков дисковой памяти (рисунок 2.34,б ). При таком способе в начале каждого блока
содержится указатель на следующий блок. В этом случае адрес файла также может быть
задан одним числом - номером первого блока. В отличие от предыдущего способа, каждый
блок может быть присоединен в цепочку какого-либо файла, следовательно фрагментация
отсутствует. Файл может изменяться во время своего существования, наращивая число
блоков. Недостатком является сложность реализации доступа к произвольно заданному
месту файла: для того, чтобы прочитать пятый по порядку блок файла, необходимо
последовательно прочитать четыре первых блока, прослеживая цепочку номеров блоков.
Кроме того, при этом способе количество данных файла, содержащихся в одном блоке, не
равно степени двойки (одно слово израсходовано на номер следующего блока), а многие
программы читают данные блоками, размер которых равен степени двойки.

18
Рис. 2.34. Физическая организация файла
а - непрерывное размещение; б - связанный список блоков;
в - связанный список индексов; г - перечень номеров блоков

Популярным способом, используемым, например, в файловой системе FAT операционной


системы MS-DOS, является использование связанного списка индексов. С каждым блоком
связывается некоторый элемент - индекс. Индексы располагаются в отдельной области диска
(в MS-DOS это таблица FAT). Если некоторый блок распределен некоторому файлу, то индекс
этого блока содержит номер следующего блока данного файла. При такой физической
организации сохраняются все достоинства предыдущего способа, но снимаются оба
отмеченных недостатка: во-первых, для доступа к произвольному месту файла достаточно
прочитать только блок индексов, отсчитать нужное количество блоков файла по цепочке и
определить номер нужного блока, и, во-вторых, данные файла занимают блок целиком, а
значит имеют объем, равный степени двойки.
В заключение рассмотрим задание физического расположения файла путем простого
перечисления номеров блоков, занимаемых этим файлом. ОС UNIX использует вариант
данного способа, позволяющий обеспечить фиксированную длину адреса, независимо от
размера файла. Для хранения адреса файла выделено 13 полей. Если размер файла меньше
или равен 10 блокам, то номера этих блоков непосредственно перечислены в первых десяти
полях адреса. Если размер файла больше 10 блоков, то следующее 11-е поле содержит адрес
блока, в котором могут быть расположены еще 128 номеров следующих блоков файла. Если
файл больше, чем 10+128 блоков, то используется 12-е поле, в котором находится номер
блока, содержащего 128 номеров блоков, которые содержат по 128 номеров блоков данного
файла. И, наконец, если файл больше 10+128+128(128, то используется последнее 13-е поле
для тройной косвенной адресации, что позволяет задать адрес файла, имеющего размер
максимум 10+ 128 + 128(128 + 128(128(128.

19
5.5 Права доступа к файлу
Определить права доступа к файлу - значит определить для каждого пользователя набор
операций, которые он может применить к данному файлу. В разных файловых системах
может быть определен свой список дифференцируемых операций доступа. Этот список
может включать следующие операции:
создание файла,
уничтожение файла,
открытие файла,
закрытие файла,
чтение файла,
запись в файл,
дополнение файла,
поиск в файле,
получение атрибутов файла,
установление новых значений атрибутов,
переименование,
выполнение файла,
чтение каталога,
и другие операции с файлами и каталогами.
В самом общем случае права доступа могут быть описаны матрицей прав доступа, в
которой столбцы соответствуют всем файлам системы, строки - всем пользователям, а на
пересечении строк и столбцов указываются разрешенные операции (рисунок 2.35). В
некоторых системах пользователи могут быть разделены на отдельные категории. Для всех
пользователей одной категории определяются единые права доступа. Например, в системе
UNIX все пользователи подразделяются на три категории: владельца файла, членов его
группы и всех остальных.

Рис. 2.35. Матрица прав доступа

Различают два основных подхода к определению прав доступа:


избирательный доступ, когда для каждого файла и каждого пользователя сам владелец
может определить допустимые операции;

20
мандатный подход, когда система наделяет пользователя определенными правами по
отношению к каждому разделяемому ресурсу (в данном случае файлу) в зависимости от того,
к какой группе пользователь отнесен.

6. Интерфейс пользователя
До сих пор мы рассматривали взаимодействие с ОС, выполняемое из программы при
помощи вызовов API - интерфейса прикладного программиста. Теперь рассмотрим
взаимодействие вне программы - через команды, вводимые с клавиатуры терминала в
интерактивных системах или поступающие во вводном потоке в пакетных системах. В
первом случае, как правило, новая команда вводится после выполнения предыдущей, и сама
новая команда или ее параметры могут выбираться в зависимости от результатов этого
выполнения. Во втором случае задается сразу целая последовательность команд, и
возможные отклонения от последовательного их выполнения должны задаваться явным
образом. Из таких различий в технологии взаимодействия пользователей с системой
вытекают естественные различия в интерактивных и пакетных командных языках, но по мере
расширения командных языков они имеют тенденцию к сближению: в интерактивные
командные языки включаются возможности задания последовательностей команд, а в
пакетные - более гибкие средства управления последовательностью выполнения.

6.1. Командный язык и командный процессор


Команды представляют собой инструкции, сообщающие ОС, что нужно делать. Команды
могут восприниматься и выполняться либо модулями ядра ОС, либо отдельным процессом, в
последнем случае такой процесс называется командным интерпретатором (оболочкой - shell).
Набор допустимых команд ОС и правил их записи образует командный язык (CL - control
language).
Большинство запросов пользователя к ОС состоят из двух компонент, показывающих:
какую операцию следует выполнить и в каком окружении (environment) должно происходить
выполнение операции. Могут различаться внутренние и внешние операции-команды.
Выполнение внутренних операций производится самим командным интерпретатором,
выполнение внешних требует вызова программ-утилит. Наличие в составе командного языка
внутренних команд представляется совершенно необходимым для тех случаев, когда
командный интерпретатор является отдельным процессом. Среди команд имеются такие, в
которых выполняются системные вызовы, изменяющие состояние самого командного
интерпретатора, если для них интерпретатор будет создавать новые процессы, то изменяться
будет состояние нового процесса, а не интерпретатора. Примеры таких команд: chdir -
изменение рабочего каталога для интерпретатора, wait - интерпретатор должен ждать
завершения порожденного им процесса и т.п. Программы-утилиты (их загрузочные модули)
записаны в файлах на внешней памяти. При их вызове порождаются процессы, и утилиты
выполняются в контексте этих процессов. Вызов и выполнение программ-утилит ничем не
отличаются от вызова и выполнения приложений. Командный интерпретатор порождает
процессы-потомки и выполняет в них заданные программы, используя для этого те же самые
системные вызовы, которые мы рассмотрели в главе 4. Задание операции в командном языке,
таким образом, может иметь вид имени программного файла, который должен быть
выполнен.
Окружением или средой (далее эти слова используются как синонимы) называется то, что
отличает одно выполнение программы от другого. Например, при выполнении программы-
компилятора должны быть определены следующие компоненты выполнения:
какую программу следует выполнить;
откуда программа должна взять исходные данные;

21
куда программа должна поместить результат компиляции;
где находятся библиотеки системы программирования;
должен или не должен формироваться листинг;
должны ли выдаваться предупреждения о возможных ошибках;
и т.д., и т.п.
Окружение может быть локальным или глобальным. В первом случае параметры
окружения устанавливаются только для данного конкретного выполнения данной конкретной
программы-процесса и теряются по окончании выполнения. Во втором случае параметры
окружения сохраняются и действуют все время до их явной отмены или переустановки.
Каким образом параметры могут быть переданы программе? Можно назвать такие
возможные механизмы передачи параметров:
если командный интерпретатор выполняется как процесс, то он может послать процессу-
программе параметры в виде сообщения;
если командный интерпретатор является ядром ОС, то он копирует параметры в
системную область памяти, и программа может получить их при помощи специального
системного вызова;
если командный интерпретатор участвует в порождении процесса-программы (а это
обычно так и бывает, независимо от того, является интерпретатор модулем ядра или
процессом), то параметры могут быть записаны в адресное пространство нового процесса
сразу при его создании.
Переменные окружения могут быть системными или пользовательскими. Системные
имеют зарезервированные символьные имена и интерпретируются командным
интерпретатором либо другими системными утилитами. Например, типичной является
системная переменная окружения path, значение которой задает список каталогов для поиска
программ командным интерпретатором. Пользовательские переменные создаются,
изменяются и интерпретируются пользователями и приложениями. Чтобы окружение могло
быть использовано, в системе должны быть средства доступа к нему. На уровне команд - это
должна быть команда типа show, выводящая на терминал имена и значения всех переменных
глобального окружения, на уровне API - системный вызов getEvironment, возвращающий
адрес блока глобального окружения.
Внутреннее представление глобального окружения - всегда текстовое, представленное в
ключевой форме, как в команде set. Это объясняется тем, что окружение интерпретируется
прикладными процессами, а именно текстовый тип может быть интерпретирован наиболее
гибким образом.
Процессы вводят данные из файла системного ввода, с которым по умолчанию связана
клавиатура, а выводят - в файл системного вывода, по умолчанию - на экран терминала.
Переадресация ввода дает возможность использовать в качестве входных данных программы
данные, заранее записанные в файл, причем программа вводит и интерпретирует эти данные
как введенные с клавиатуры. Переадресация вывода сохраняет данные, которые должны
выводиться на экран, в файле

6.2. Командные файлы и язык процедур


Принцип пользователя диктует необходимость короткого обращения к часто
выполняемым последовательностям команд. Простым и эффективным решением этой задачи
является запись такой последовательности в текстовый файл и обращение к ней в
дальнейшем по имени файла. Мы будем называть такие файлы командными файлами. В
интерактивных системах их иногда также называют пакетными файлами (batch file), а в
пакетных - файлами процедур JCL. Командный интерпретатор должен при вводе команды-
обращения к такому файлу распознать тип файла (иногда признак обращения к командному

22
файлу требуется указать в самой команде) и далее считывать и интерпретировать команды из
файла.
В простейшем случае командный файл содержит неизменяемую последовательность
команд и является просто аббревиатурой этой последовательности. Но сервис,
обеспечиваемый инвариантными последовательностями, явно недостаточен. Например, для
программиста типичным является "сценарий" работы, состоящий из многократного
повторения таких шагов:
редактирование исходного модуля;
компиляция;
компоновка;
выполнение.
Каждый шаг связан с вызовом новой программы, следовательно, с новой командой.
Очевидно, что при записи такого сценария в командный файл мы должны обеспечить для
него хотя бы один параметр - имя исходного модуля. Параметры являются совершенно
необходимым свойством для командных файлов. Параметры нетрудно обрабатывать простой
текстовой подстановкой.
Очевидно также, что в том же сценарии не имеет смысла компоновать, а тем более
выполнять программу, если при компиляции в ней обнаружены ошибки. Отсюда -
необходимость управлять последовательностью выполнения команд в командном сценарии.
Простейшим вариантом такого управления является включение в команду условия ее
выполнения, более сложный и гибкий вариант - условный переход на ту или иную команду. В
условии выполнения или перехода должен анализироваться код завершения одной или
нескольких предыдущих команд. Общепринятым является успешное завершение программ и
команд с кодом 0. Код завершения может формироваться программой, выполняющей
команду, как параметр системного вызова exit и восприниматься процессом-родителем
(командным интерпретатором) в системном вызове wait.
Командные языки ОС обладают всеми возможностями языков программирования, и, в
принципе, пригодны для создания не только командных процедур, но и некоторых программ
обработки данных. Выполнение командных файлов в режиме интерпретации, конечно, делает
такие программы менее эффективными, чем программы, написанные на языках
компилирующего типа, но создает в них некоторые дополнительные возможности и
вырабатывает некоторый особый стиль программирования.

6.3. Проблема идентификации адресата


При параллельном выполнении нескольких процессов возникает проблема
взаимодействия пользователя с ними: при появлении на экране сообщения, как пользователь
определит, какой из процессов это сообщение выдал? при вводе сообщения пользователем,
как ОС определит, какому процессу сообщение адресовано?. Решение этой проблемы зависит
прежде всего от степени интерактивности процессов (насколько часто они обмениваются
сообщениями с пользователем). Если процессы не очень интерактивны, то им можно
разрешить квазиодновременный вывод на терминал: их сообщения могут чередоваться, но
каждое сообщение должно быть неделимым. В этом случае выводимое сообщение должно
нести в себе и идентификацию процесса, его выдавшего. Дейкстра [7] подробно рассмотрел
реализацию диалогового взаимодействия такого рода с помощью семафоров. Им показано,
что для этого случая ответы пользователя должны либо также содержать идентификатор
процесса-адресата, либо пара действий вопрос-ответ должна быть одной транзакцией. В
последнем случае, однако, задержка ответа надолго блокирует общий канал обмена между
процессами и пользователем, поэтому у пользователя также должна быть возможность
откладывания ответа с последующим возвращением к диалогу с этим же процессом.

23
Подход, предполагающий явное адресование сообщений, становится излишне
громоздким, если пользователь работает с существенно интерактивными процессами. Общая
идея обеспечения взаимодействия для такого случая состоит в том, что в каждый момент
времени только одному процессу (по выбору пользователя) разрешается быть интерактивным
(foreground - на переднем плане), то есть, иметь доступ к терминалу. Остальные процессы
(background - фоновые) выполняются без доступа к терминалу. В распряжении пользователя
имеются средства изменения статуса процесса - перемещения его с заднего плана на
передний (текущий процесс переднего плана при этом отодвигается на задний план).

6.4. WIMP-интерфейс
Интерфейс командной строки (но не командные файлы!) на сегодняшний день уже можно
считать отходящим в прошлое, хотя прогнозировать его окончательный уход мы не беремся.
Программируемые видеотерминалы дают возможность выводить информацию в любую
позицию экрана и, следовательно, использовать все пространство экрана для организации
взаимодействия между ОС и пользователем. Современные интерфейсы как приложений, так
и ОС можно охарактеризовать как полноэкранные, графические, объекно-ориентированные.
Полноэкранный интерфейс строится на основе принципа согласованности, который
состоит в том, что у пользователя формируется система ожидания одинаковых реакций на
одинаковые действия. Основными компонентами интерфейса являются панели, диалоги и
окна.
Панель - это информация, определенным образом сгруппированная и расположенная на
экране. Основные типы панелей:
меню - содержит один или более списков объектов, представляющих группы действий,
доступных пользователю;
панель ввода - отображает поля, в которые пользователь вводит информацию;
информационная панель - отображает защищенную информацию (данные, сообщения,
справки);
списковая панель - содержит один или более списков объектов, из которых пользователь
выбирает один или несколько и запрашивает одно или несколько действий над ними;
панель-канва - свободное пространство, на котором можно размещать другие объекты
интерфейса, такие как:
кнопки различных видов и различной функциональности;
элементы выбора;
статические текстовые поля;
протяжки;
другие панели и т.д.
Диалог - это последовательность запросов между пользователем и компьютером: запрос
пользователем действия, реакция и запрос компьютера, ответное действие пользователя и т.д.
Диалог включает в себя запросы и навигацию - переходы из одной панели в другую.
Информация, вводимая пользователем в ходе диалога, может удерживаться только на уровне
данной панели или сохраняться.
Общие принципы панельного интерфейса в основном не зависят от типа применяемых
терминалов. Однако, сочетание графических видеоадаптеров с высокой разрешающей
способностью с общим увеличением вычислительной мощности (быстродействие и объем
памяти) персональных вычислительных систем позволяет существенно изменить общий
облик экрана. Можно определить следующие основные направления этих изменений:
многооконность, целеуказание, иконика. Такие интерфейсы получили название WIMP
(Windows, Icons, Menus, Pointer). Первое воплощение идеи WIMP нашли в разработках

24
фирмы Xerox, а первая их коммерчески успешная реализация состоялась в компьютерах
Apple Macintosh в 1985 году. Позднее идеи WIMP были приняты в Microsoft Windows, а
сейчас они воплощены практически в всех операционных системах.
Объектно-ориентированные свойства интерфейса совершенно необязательно связаны с
объектно-ориентированной структурой ОС. Так, например, OS/400 является объектно-
ориентированной системой с объектно-ориентированным интерфейсом, Windows NT v.3.51
была объектно-ориентированной ОС без объектно-ориентированного интерфейса, OS/2 и
Windows 9x - не объектно-ориентированные ОС с объектно-ориентированным интерфейсом.
Объектно-ориентированный интерфейс обычно связывают с графическим интерфейсом, но
это необязательно. Так, в той же OS/400 предусмотрены две модели интерфейса: текстовая и
графическая, обе в полной мере объектно-ориентированные.
Важным аспектом объектной ориентации является настройка интерфейса для
конкретного пользователя. Обычно, если интерфейс рассматривается с точки зрения
приложений, отмечается полезность создания нескольких форм интерфейса,
ориентированных на пользователя разной квалификации - новичка, опытного,
профессионала. Хотя та же задача может ставиться и перед интерфейсом ОС, более важной,
на наш взгляд является интеграция интерфейса с системой безопасности ОС. Интерфейс
должен показывать пользователю только те объекты и предоставлять ему только те команды,
к которым данный пользователь имеет доступ. Такое возможно в тех ОС, где система
безопасности тесно связана с объектно-ориентированными свойствами ОС. Настройки
интерфейса могут являться частью профиля пользователя.

25