/
Text
Д. Цнкритзис, Ф, Бернстайн
ОПЕРАЦИОННЫЕ
СИСТЕМЫ
OPERATING
SYSTEMS
Dionysios C. Tsichritzis and Philip A. Bernstein
Department of Computer Science
University of Toronto
Toronto, Ontario
ACADEMIC PRESS
NEW YORK SAN FRANCISCO LONDON
A SUBSIDIARY OF HARCOURT BRACE JOVANOVICH, PUBLISHERS
1974
Д. Цикритзис, Ф. Бернстайн
ОПЕРАЦИОННЫЕ
СИСТЕМЫ
Перевод с английского
В. Л. УШКОВОЙ и Н. Б. ФЕЙГЕЛЬСОН
Под редакцией
И. Б. ЗАДЫХАЙЛО И В. В. МАРТЫНЮКА
ИЗДАТЕЛЬСТВО «МИР»
МОСКВА 1977
УДК 681.142.2
В книге проводится глубокий анализ всего ком-
плекса проблем современных операционных систем.
В отличие от других книг по той же тематике она
ориентирована в первую очередь на выявление общих
принципов построения различных операционных си-
стем. Эти принципы излагаются в сжатой и ясной
форме, иллюстрируются на примерах распространен-
ных систем; специально рассматриваются две модель-
ные системы, пригодные для использования в учеб-
ных целях.
Книга может служить хорошим учебником сту-
дентам и аспирантам, изучающим системное програм-
мирование. Она будет полезна также специалистам
по вычислительной технике и программированию.
Редакция литературы пл математическим наукам
20204-031 © 1974, by Academic Press, Inc.
И-----------.— 31-77
041 (01)-77 © Перевод на русский язык, «Мир», 1977
ПРЕДИСЛОВИЕ
РЕДАКТОРОВ ПЕРЕВОДА
Изучение структуры современных операционных систем — од-
ного из наиболее важных разделов математического обеспечения
ЭВМ — часто бывает сопряжено с трудностями, которые объясня-
ются как сложностью самого предмета, так и тяжеловесностью из-
ложения в руководствах (обычно являющихся описаниями конк-
ретных фирменных разработок). В отличие от таких руководств
предлагаемая книга систематизирует в достаточно общем и в то же
время наглядном виде основные понятия и принципы, которым под-
чиняется поведение различных операционных систем. Благодаря
удачно выбранной методике авторы сумели в сжатой и доступной
форме изложить основные достижения современной теории опера-
ционных систем.
В целом книгу можно признать лучшей из имеющихся в настоя-
щее время монографий по операционным системам. Выявляя общие
принципы построения различных операционных систем, авторы
в каждой главе четко и просто формулируют постановку соответст-
вующей задачи, описывают один или несколько наиболее устояв-
шихся подходов к ее решению, приводят ссылки на последние ре-
зультаты в этой области и ставят интересные проблемы, требующие
творческого осмысливания изучаемого материала. Весьма ценной
представляется проведенная авторами унификация терминологии;
особенно тщательно они разработали определения вводимых поня-
тий.
Книгу можно рекомендовать специалистам различной квалифи-
кации и студентам как для самостоятельного изучения предмета,
так и в качестве пособия, облегчающего усвоение учебного мате-
риала. Она окажет также существенную помощь преподавателям
при подготовке лекций, практических занятий и теоретических
семинаров,
И. Б. Задыхайло
В. В. Мартынюк
ПРЕДИСЛОВИЕ АВТОРОВ
Понятию «операционная система» трудно дать точное определе-
ние. Слово «система» употребляется во всевозможных значениях как
программистами, так и инженерами, а слово «операционная» мало
что уточняет. Как правило, пользователи хотят, чтобы им были пре-
доставлены возможности, отличные от тех, которые обеспечивает
оборудование. Чтобы разрешить эту проблему, обычно применяют
набор программ, который служит своего рода переводчиком с язы-
ка возможностей оборудования на язык требований пользователя.
Такой набор программ и называют операционной системой. Сейчас
мы не будем ни пытаться разъяснять дальше, ни запутывать этот
термин. В главе 1 мы изложим нашу точку зрения на то, из чего
состоит операционная система. Мы надеемся, что, дойдя до конца
книги, читатель будет в состоянии узнавать операционную систему,
когда она ему встретится.
Большинству пользователей не нужно досконально знать опе-
рационную систему, на которой работают их программы. Им при-
ходится только подчиняться ограничениям, налагаемым системой,
таким, как размеры сегментов памяти или язык управления рабо-
тами. Точно так же, человек, составляющий программу на ФОРТ-
РАНе, не обязан понимать все подробности устройства компиля-
тора с ФОРТРАНа, которым он пользуется.. Однако все согласны
с тем, что в подготовку специалистов по математическому обеспе-
чению должен обязательно входить курс принципов организации
операционных систем. Цель нашей книги — дать читателю основу
для такого курса. Мы не пытаемся излагать общую методологию
построения операционных систем, а постараемся представить в
сжатой и доступной форме фундаментальные понятия и принципы,
которым подчинено поведение операционных систем.
Мы старались, насколько возможно, придерживаться формы за-
писи, принятой в литературе. Особые трудности встретились при
этом в отношении оборудования, потому что определения, приме-
няемые различными изготовителями, часто противоречат друг дру-
гу. В сомнительных случаях мы уступали силе больших чисел и
применяли форму записи, принятую в литературе фирмы IBM. При
описании алгоритмов мы не пользовались каким-либо конкретным
языком программирования, оставив за собой большую свободу в
выборе подходящих структур управления и основных операторов.
Распространенные языки программирования, такие, как PL/I,
слишком громоздки, чтобы пользоваться ими для описания, а бо-
лее подходящие для этой цели языки, как, например, PASCAL,
недостаточно широко известны. Четкие определения правил записи
мы дадим в разделах, где эти правила вводятся.
Эта книга предназначается в первую очередь для студентов 4-го
(последнего) курса и аспирантов 1-го года обучения. Содержащий-
ся в ней материал рассчитан на изучение в течение одного семестра
аналогично курсу 14, указанному в учебной программе, которая
была рекомендована АСМ в 1968 г. С 1969 года такой курс читается
в университете Торонто; его прослушивает около ста студентов
ежегодно. Курс и книга разработаны в соответствии с рекоменда-
циями специальной комиссии COSINE по операционным системам
[Деннинг и др., 1971]. Мы настоятельно советуем лектору, соби-
рающемуся читать курс по операционным системам, ознакомиться
с докладом этой комиссии.
Студентам, которые слушают этот курс в нашем университете,
предварительно читаются курсы по структурам данных и по про-
ектированию языков и компиляторов. Мы не считаем такую под-
готовку абсолютно необходимой, но она очень помогает студентам
достичь определенной зрелости в области системного программи-
рования. Мы не рассчитывали на высокий уровень подготовки сту-
дентов, для которых предназначена эта книга. Предполагается
только, что у них имеется некоторый опыт в области математическо-
го обеспечения. Особенно полезно, если студенты уже писали какие-
то длинные программы и имеют некоторое представление о труд-
ностях, с которыми сталкиваешься при непосредственном контак-
те с вычислительными системами, таких, как война с ограничения-
ми, налагаемыми языком управления работами. Кроме того, важно,
чтобы читатель кое-что знал о списках и очередях. Этот материал,
выделенный в приложение I, может быть изложен на первых се-
минарских занятиях для студентов со слабой подготовкой.
Многие спорные вопросы, касающиеся структуры операцион-
ных систем, хорошо разработаны. Задачи управления процессами,
процессорами и памятью, которые рассматриваются в части I,
одно время широко обсуждались в литературе. Несмотря на то
что в этих областях еще много открытых вопросов, их можно изло-
жить с приемлемой ясностью. К сожалению, не все спорные вопро-
сы решаются столь же элегантно. В части II речь идет о предмете,
формальная разработка которого все еще находится в стадии за-
рождения. Ввод-вывод, файлы, гарантия секретности, защита, ме-
тоды проектирования, надежность, оценка исполнения и методы
реализации — все это важные аспекты операционных систем. Не-
смотря на то что приемы, связанные с этими темами, носят доволь-
но частный характер, нам кажется, что они тем не менее должны
входить во всякое вводное изложение принципов построения опе-
рационных систем.
Некоторые основные понятия из области операционных систем
вводятся в нашей книге довольно поздно, например виртуальные
машины — в главе 8. Опыт показывает, что студентам трудно оце-
нить эти понятия, пока они не научатся устанавливать связь меж-
ду идеями и конкретными операционными системами. Несмотря на
то что часть материала начальных глав можно изложить стройнее,
если использовать эти понятия, мы считаем, что это может оказать-
ся слишком сложно для вводного курса.
По проблемам анализа операционных систем написано много
статей. В этом направлении получены важные результаты, кото-
рые часто позволяют глубже понять поведение операционных си-
стем. Мы постарались избежать упоминаний о большинстве из этих
результатов по двум причинам. Во-первых, эти результаты в боль-
шей степени относятся к разделам прикладной математики, чем к
области операционных систем. Во-вторых, этот материал больше
подходит для отдельного, предназначенного для аспирантов курса
по моделированию и анализу операционных систем, чем для ввод-
ного курса, который посвящен основным идеям. Во всех разделах
книги имеется много ссылок на теоретическую литературу. Анно-
тированная библиография может послужить руководством для ин-
тересующихся читателей. Однако мы все-таки решили сделать одно
исключение. В приложении II приведен краткий обзор вычисли-
тельных структур — материал, относящийся непосредственно к
главе 2. Поскольку большую часть литературы по этой теме трудно
достать, мы подумали, что для интересующегося читателя стоит
добавить краткий разбор.
БЛАГОДАРНОСТИ
Многие из идей, изложенных в этой книге, явились результа-
том работы, проделанной группой разработчиков проекта SUE
в составе: Атвуд, Грушков, Кларк, Севсик, Р. Холт, Хорнинг и
Цикритзис. Члены группы оказали влияние не только на содержа-
ние, но и на дух этой книги. Авторы выражают этой группе глубо-
кую признательность за огромный вклад, внесенный ею в создание
книги.
Значительную помощь при редактировании первых вариантов
глав оказали многие студенты и преподаватели факультета. Мно-
гими своими достоинствами окончательный вариант рукописи обя-
зан их замечаниям. В частности, нам помогали Баллард (гл. 8, 9 и
приложение III), Готлиб (гл. 7), Р. Холт (гл. 8), Хорнинг (гл. 1 й 2),
Хорспул (гл. 4 и наборы заданий), Лазовска (гл. 4 и 5), Метц-
гер (гл. 9), Севсик (гл. 3, 7 и 10) и Томпа (гл. 4—6). Аннотирован-
ный список литературы составлен на основе первоначального ва-
рианта, подготовленного Бантом. Мы хотели бы поблагодарить
также госпожу Лисков за помощь в разъяснении многих туманных
мест в нашем описании операционной системы «Венера» в гл. 10.
Замечания по всему последнему варианту рукописи, сделанные
Керниганом, очень помогли найти и исправить отдельные слабые
места.
Мы особенно благодарны нашему другу и коллеге Свенсону,
который внимательно прочитал черновик окончательного варианта,
что привело ко многим изменениям как на техническом, так и на
методическом уровне. В частности, многие его идеи относительно
управления памятью оказали значительное влияние на строение и
содержание гл. 4—6.
Мы признательны также многим другим коллегам, слишком
многочисленным, чтобы всех их здесь упоминать, за интересное и
содержательное обсуждение принципов операционных систем в
разнообразных аспектах.
Наконец, большую помощь в оформлении рукописи оказывали
на разных стадиях работы Олдхэм, Шум и Стил, которым мы также
хотели бы выразить свою благодарность.
ЗАМЕЧАНИЯ
ДЛЯ ПРЕПОДАВАТЕЛЯ
Мы пришли к заключению, что весьма полезно проводить па-
раллельно с лекциями семинары, на которых достаточно подроб-
но разбиралась бы какая-то конкретная система, и демонстриро-
вать студентам, как различные идеи, содержащиеся в курсе, реа-
лизуются совместно. В главе 10 мы рассматриваем два примера
операционных систем. Дополнительные примеры можно найти в
книгах Хоара и Перро [1972] и Сэйерса [1971]. Мы советуем про-
водить эти обсуждения систем в самом начале семестра, чтобы обос-
новать таким образом материал курса. Большинство слушателей,
особенно студенты-выпускники, очень мало сталкивались с настоя-
щими операционными системами. Едва ли можно ожидать, что их
приведут в восторг решения непонятных им проблем.
Материал книги дополняется помещенными в конце каждой
главы заданиями, которые служат многим полезным целям. Во-
первых, в них разрабатываются вопросы, которые в основном тек-
сте только бегло затронуты. Во-вторых, они помогают соотнести
некоторые абстрактные понятия об операционных системах с дейст-
вительным положением в этой области. В-третьих, в них указаны
статьи для дополнительного чтения. Многие из заданий по необхо-
димости остаются открытыми, т. е. у них нет единственного верного
ответа. Такие задания предназначены для того, чтобы побудить
студентов рассмотреть несколько взаимоисключающих решений.
Их можно использовать как в качестве тем для обсуждения на за-
нятиях, так и для домашних заданий.
Требования, предъявляемые к слушателям нашего курса в уни-
верситете Торонто, таковы:
1) экзамен, дающий преподавателю возможность удостоверить-
ся, что студенты усваивают лекционный материал; .
2) большое домашнее задание, содержащее более значительные,
побуждающие к размышлению задачи, которые студенты могли бы
глубоко разрабатывать;
3) курсовой проект, который ближе знакомит студентов с дейст-
вительным положением в области операционных систем.
Если группа небольшая, то вместо экзамена можно предложить
несколько коротких заданий. И задания для контрольной работы,
и домашние задания можно выбрать из приведенных в конце каж-
дой главы.
Ниже мы подробно изложим требования, предъявляемые к кур-
совому проекту, так как он представляет собой серьезное испыта-
ние и для преподавателя, и для студентов. Нелегко запланировать,
проконтролировать и оценить сотню проектов в год. Мы испробо-
вали несколько подходов.
1. Сочинение-обзор операционных систем в каком-либо аспек-
те. В наборы задач мы включили предполагаемые темы сочинений.
В университете Торонто сочинения прошлых лет сохраняются и
сдаются в библиотеку как пособия для будущих студентов. Мы счи-
таем, что сочинения особенно полезны в первые годы преподавания
курса. Они требуют минимального руководства и образуют хоро-
шую местную библиотеку по темам, которые не так интересны, что-
бы включать их в лекционный курс. В частности, весьма ценным мо-
жет стать собрание описаний распространенных систем. Когда курс
прочитан несколько раз, становится трудно избежать повторения
тем. В этот момент можно перенести центр тяжести на другие типы
проектов. Однако сочинения всегда должны оставаться как вариант
для некоторого рода студентов, таких, как слушатели, направлен-
ные для повышения квалификации, которые умеют хорошо про-
граммировать, но не особенно начитанны.
2. Оценка объединенными усилиями студентов каких-либо ас-
пектов проекта или реализации операционной системы. Примером
работытакого рода служит проект «Розеттский камень», первоначаль-
но предложенный Вулфом и предназначенный для оценки языков
системного программирования [Вулф и др., 1972]. Большое число
студентов программирует на двух или трех языках набор стандарт-
ных задач, таких, как алгоритмы синхронизации процессов и уп-
равления памятью. Кроме программ, студенты должны написать
комментарий, в котором сравниваются разные языки. Мы пробо-
вали давать студентам проекты такого типа, но с ограниченным ус-
пехом. Основная трудность состоит в том, что для оценки языков
нужна довольно высокая квалификация. Поскольку большинство
студентов не особенно много занимаются оценками, основная цен-
ность проекта для них состоит в изучении небольшого числа новых
языков и решений нескольких небольших задач. Мы считаем, что,
хотя проекты такого рода заслуживают внимания, они, вероятно,
больше подходят для курсов по разработке математического обес-
печения или по программированию больших систем, чем по опе-
рационным системам.
3. «Игрушечная» операционная система, использующая смоде-
лированное с учебными целями оборудование. В приложении III
мы в общих чертах описываем основные проблемы, возникающие
при составлении плана и руководстве таким проектом. Студенты,
работая группами по двое или по трое, моделируют простую ма-
шину и затем пишут для нее небольшую операционную систему.
Мы неоднократно пробовали давать этот проект, и всегда с большим
успехом. Это может оказаться несколько дорого с точки зрения за-
трат машинного времени, но зато студенты приобретают определен-
ный опыт в конструировании сложных систем. Попутно такой
проект приносит пользу тем, что студенты впервые знакомятся с
настоящими задачами программирования, поскольку должны напи-
сать коллективно относительно большую программу. Им прихо-
дится заниматься организационными вопросами, которые были би-
чом для многих проектов операционных систем. В университете
Торонто мы широко используем в качестве задания «игрушечную»
операционную систему, проект которой был написан Р. Холтом для
работы на языке программирования TOPPS [Холт и Кинред, 1972].
Система TOPPS [Зарник и др., 1970] может работать в любой си-
стеме, в которой может работать система XPL, генерирующая ком-
пиляторы. Мы надеемся, что в ближайшем будущем сможем пре-
доставить магнитные ленты с программами и документацию уни-
верситетам, которые захотят испробовать наш проект.
4. Математическое обеспечение для мини-машины. Проект тако-
го типа может быть очень интересным, но он предполагает наличие
очень гибкой мини-машины. Если имеются подходящие технические
средства, то можно предложить в качестве хороших курсовых про-
ектов много интересных пакетов программ, таких, как простой вы-
числитель, буферизация ввода-вывода или система для работы
с файлами. Имеется несколько статей, в которых описано такое
оборудование, например [Маршленд иДартар, 1973]. У нас в уни-
верситете этот подход будет принят в курсе по операционным си-
стемам для подготовленных студентов. Однако руководить мно-
гими проектами такого рода, по-видимому, нелегко.
5. Создание реальных программ для университетского вычис-
лительного центра или для промышленных предприятий. Мы за-
ключили соглашение о сотрудничестве со своим вычислительным
центром. По этому соглашению 5—10 студентов работают под ру-
ководством сотрудников вычислительного центра над заданиями,
которые предлагают, оценивают и в конечном счете используют
сотрудники вычислительного центра. И вычислительный центр,
и студенты работают с энтузиазмом, но нам кажется, что если число
студентов, принимающих участие в такой работе, увеличить, то
это приведет к серьезным организационным трудностям. Для того
чтобы студент мог успешно выполнить задание, ему нужен инди-
видуальный руководитель, а мы располагаем лишь ограниченным
числом руководителей. Такой проект особенно подходит студентам,
у которых мало практического опыта. Студенты, имеющие произ-
водственный опыт, обычно не выбирают в качестве проекта очеред-
ную системную программу. По той же причине, по которой програм-
мирование реальной задачи захватывает новичка, для опытного
системного программиста очень полезно задание типа обзорного
сочинения.
Какие проекты окажутся наиболее подходящими для конкрет-
ной школы, зависит главным образом от того, что за средства име-
ются в ее распоряжении. Мы будем рады помочь в меру своих воз-
можностей, если у читателей возникнут какие-либо вопросы об
особенностях указанных проектов.
Часть I
ПРИНЦИПЫ
В первых пяти главах этой книги мы рассмотрим распределение
основных ресурсов вычислительной системы, т. е. процессоров и
памяти. Глава 1 дает общее представление о том, что делают опе-
рационные системы и как они обычно бывают устроены. В главе 2
вводится основное понятие процесса как средства, помогающего
понять взаимодействие работ, выполняемых в вычислительной сис-
теме. В главе 3 понятие процесса используется для того, чтобы по-
казать, как единственный процессор можно распределить между
несколькими независимыми задачами. Главы 4 и 5 охватывают во-
просы распределения основной памяти и способы ее расширения
за счет периферийных устройств для хранения информации.
Способы управления процессами, процессорами и памятью ши-
роко обсуждались в литературе. Основные проблемы этой области
программирования хорошо разработаны. Поэтому главная задача
состоит в том, чтобы преподнести материал на строгом профессио-
нальном и хорошем методическом уровне.
Глава 1
ОПЕРАЦИОННЫЕ СИСТЕМЫ.
ФУНКЦИИ И ОСНОВНЫЕ ПОНЯТИЯ
1.1. Введение
Большинство современных вычислительных систем — это «гро-
моздкие чудовища». Типичная машина средней величины пред-
ставляет собой сложное переплетение многих устройств аппарат-
ного оборудования, таких, как центральные процессоры, опера-
тивная память, барабаны, диски, лентопротяжные устройства, тер-
миналы с пишущими машинками, устройства ввода перфокарт и
вывода на печать. Чтобы помочь человеку преодолеть трудности
управления всеми этими устройствами, система снабжена програм-
мным оборудованием, или математическим обеспечением, которое
делает систему аппаратного оборудования более удобной для поль-
зования. Программное оборудование освобождает тех, кто желает,
чтобы их программы выполнялись на аппаратном оборудовании дан-
ной вычислительной системы, т. е. пользователей, от необходимости
иметь дело со специфическими свойствами каждого устройства.
Пользователям нужны такие операции, как «выполнить эту про-
грамму» или «запомнить этот файл». Технические детали выделе-
ния памяти и процессора для программы или места на диске — это
забота программного оборудования. Программное оборудование не
только облегчает пользование машиной — оно необходимо для того,
чтобы сделать возможным разделение системы между несколькими
пользователями. Современные вычислительные системы очень до-
роги. Средний пользователь просто не может себе позволить иметь
собственную систему или платить за единоличную эксплуатацию
большой системы. Поэтому экономическая необходимость вынуж-
дает его использовать систему совместно с другими пользователями.
И управление ресурсами системы, которое сделало бы возможным
такое разделение, тоже возлагается на программное оборудование.
Цель этой главы — дать читателю представление о требованиях,
предъявляемых к эксплуатационным качествам той части програм-
много оборудования вычислительной системы, которая называется
операционной системой, и ее функциях. Однако, прежде чем огра-
ничивать предмет нашего обсуждения операционными системами,
очень важно разобраться в основных отличительных свойствах
обеих составных частей вычислительной системы, т. е. аппаратного
и программного оборудования,
1.1.1. Аппаратное оборудование
Аппаратное оборудование вычислительной системы состоит из
одного или нескольких центральных блоков обработки данных
(называемых также центральными процессорами или просто про-
цессорами), которые могут выполнять команды на языке машины;
непосредственно адресуемой памяти (называемой также оператив-
ной памятью)', периферийных устройств (именуемых также
устройствами ввода-вывода), которые обеспечивают ввод и вывод
информации для системы и играют роль вспомогательной памяти.
Процессор обычно состоит из нескольких регистров определенной
длины, предназначенных для запоминания результатов, и арифмети-
ческого устройства, которое выполняет команды. Оперативная па-
мять делится на участки, состоящие из одинакового числа битов
и называемые словами. Слова обычно бывают той же длины, что и
регистры. Каждому слову памяти соответствует свое имя, называемое
адресом или номером ячейки. Слова могут содержать либо команды,
либо данные. В одном из регистров процессора, регистре адреса
команды, находится адрес следующей команды, которую будет вы-
полнять арифметическое устройство. Команды обычно выполняют-
ся последовательно в порядке возрастания адресов до тех пор, пока
очередная команда не нарушит этот порядок, изменив содержимое
регистра адреса команды и вызвав тем самым переход к новой ячей-
ке. Здесь следует заметить, что возможна и другая архитектура вы-
числительной системы, совершенно отличная от описанной здесь
[Органик, 1973].
Хотя приведенное выше описание процессоров и памяти дает
только грубое и упрощенное представление о настоящем аппарат-
ном оборудовании, в нем вводится общеупотребительная термино-
логия, связанная с аппаратурой. В то время как свойства процес-
соров и оперативной памяти хорошо известны читателю, отличи-
тельные особенности периферийных устройств, вероятно, многим
неизвестны и поэтому будут изложены более подробно.
Периферийные устройства служат для обмена информацией меж-
ду оперативной памятью и тем или иным видом вспомогательной
памяти или визуальным средством вывода, как, например, перфокар-
ты, магнитный диск или лента, печать на бумаге. Устройства раз-
личают в зависимости от носителя, на котором запоминается ин-
формация, а также способа и скорости доступа к ней. Одни устрой-
ства, такие, как лентопротяжные или читающие с перфокарт,
строго последовательны. Они перерабатывают информацию еди-
ным потоком в порядке поступления по принципу «первым при-
шел — первым ушел» (FIFO); чтобы прочесть десятый элемент
информации, надо прочесть и первые девять. Другие носители до-
пускают более произвольный доступ к информации. Магнитные бара-
баны и диски состоят из дорожек. Вместо того чтобы последователь-
но добираться до куска информации, являющегося TV-м элементом
на ленте, можно взять этот элемент из М-й дорожки барабана. По-
скольку головки барабанов и дисков могут довольно быстро пе-
реключаться с дорожки на дорожку, среднее время, необходимое
для получения элемента информации (или время доступа), значи-
тельно меньше, чем при строго последовательном доступе. Фак-
тически на всех магнитных устройствах скорость передачи, т. е.
скорость, с которой порция информации передается, после того
как она найдена, гораздо больше, чем скорость доступа к ней. Из-
за такого свойства носителей передачу информации выгоднее ор-
ганизовывать большими порциями. Например, если десять слов
записаны на диске друг за другом, то гораздо быстрее будет про-
честь их как целый массив за одно обращение, чем выбирать их по
одному за раз. Для небольших порций информации время пере-
дачи пренебрежимо мало по сравнению со временем доступа, поэ-
тому чтение слов по одному почти в 10 раз медленнее, чем чтение
всей десятки разом.
Несмотря на то что разница в скорости разных типов носите-
лей очень велика, их связь с вычислительной системой организо-
вана довольно единообразно. Периферийные устройства обычно
связаны с центральным процессором через специализированные
вычислительные машины, называемые каналами. Связь периферий-
ного устройства с каналом осуществляется посредством блока уп-
равления устройством. Блок управления устройством — это элект-
ронное устройство, которое принимает команды канала и застав-
ляет носитель либо выполнять определенные действия (например,
изменять направление движения или переходить на другую до-
рожку), либо передавать информацию в канал или из него.
Когда программа обращается к операции ввода-вывода, система
принимает запрос, порождает нужную программу и посылает
ее по каналу. На основании информации, содержащейся в про-
грамме ввода-вывода, канал выбирает устройство и заставляет его
выполнить соответствующее действие, например читать в свою за-
поминающую среду или писать из нее. После того как операция
ввода-вывода завершится, канал должен сообщить об этом системе.
Это сообщение обычно передается посредством аппаратного преры-
вания.
Прерывание — это принудительная передача управления от вы-
полняемой программы к системе, происходящая при выполнении
определенного внешнего условия. Говорят, что прерывание раз-
решено, если запрос на него принят к выполнению. Запрашивание
и разрешение прерываний отмечаются установкой значений спе-
циальных разрядов в процессоре. Когда прерывание запрошено
и разрешено, центральный процессор прекращает текущую работу
и передает управление на определенную ячейку в оперативной па-
мяти. Системная программа, начало которой находится в этой
ячейке, проверяет регистры прерываний, чтобы установить причи-
ну прерывания. Например, прерывание могло произойти из-за
того, что устройство кончило работать или выполнялась недопус-
тимая команда. После этого система может принять соответствую-
щие меры, например послать каналу следующую команду или пре-
кратить выполнение программы.
Каналы и центральный процессор могут работать параллельно.
Поскольку давать указания каналу обязана программа централь-
ного процессора, в большинстве машин прерывания используют для
синхронизации работы этих независимых устройств. Как будет по-
казано в гл. 2, прерывания — не всегда лучший способ синхрони-
зации одновременных операций. Тем не менее, поскольку прерыва-
ния повсеместно используются в системах аппаратного оборудова-
ния, это понятие очень важно для понимания структуры систем.
1.1.2. Программное оборудование
Если бы аппаратное оборудование предоставляло пользователям
вычислительных систем в точности такие возможности, какие им
необходимы, программное оборудование было бы не нужно. Однако
для большинства пользователей форма работы с техническими при-
способлениями не особенно удобна. Кроме того, без помощи ма-
тематического обеспечения трудно организовать благополучное и
эффективное разделение системы между пользователями. Поэтому
пользователям требуется математическое обеспечение, которое спо-
собствовало бы работе их программ.
1.1.2.1. Разделение
Ресурсом называется всякий объект, который может распреде-
ляться внутри системы. Аппаратные ресурсы редко используются
в режиме разделения в том смысле, что две программы одновремен-
но работают с одним и тем же ресурсом. Принято говорить, что ре-
сурс работает в режиме разделения, если каждая из нескольких
программ полностью занимает его в течение некоторого подынтер-
вала рассматриваемого периода времени. Например, пять про-
грамм могут разделять (т. е. совместно использовать) процессор по-
ровну, если каждой дается возможность работать в течение одной
секунды из каждых пяти. Фактически таким образом происходит
разделение всех аппаратных устройств, но масштабы промежутков
времени, на которые разные устройства предоставляются прог-
раммам, существенно различны. Например, программа может на
несколько минут получить в свое распоряжение часть оперативной
памяти, но никому не разрешается больше секунды подряд поль-
зоваться процессором.
Есть два основных способа реализовать разделение. При де-
централизованном способе предполагается, что несколько программ
хотят совместно использовать некоторый ресурс и «знают о сущест-
вовании друг друга». В этом случае программы могут взаимодей-
ствовать, передавая этот ресурс друг другу. Однако большинство
систем устроено так, что пользователей не затрудняют общением
друг с другом. При централизованном способе разделения ответст-
венность за справедливое и эффективное распределение ресурсов
системы возлагается на отдельную программу, так что программам
больше не нужно взаимодействовать, чтобы удовлетворить свои за-
просы на ресурсы. Когда программе требуется ресурс, она просто
запрашивает его у «распределителя ресурсов». Идеи распределения
и разделения ресурсов занимают центральное место среди прин-
ципов операционной системы. В следующих разделах мы рассмот-
рим основные задачи распределения ресурсов и способы их реали-
зации.
1.1.2.2. Другие возможности, предоставляемые программным
оборудованием
Периферийные устройства передают информацию существенно
медленнее, чем ее обрабатывает центральный процессор. Для того
чтобы не заставлять центральный процессор дожидаться нужной
информации, устройство должно передать ее в оперативную па-
мять, до того как она непосредственно потребуется процессору.
К тому времени, когда центральный процессор только начинает
обрабатывать информацию, находящуюся в оперативной памяти,
периферийное устройство уже должно было начать обмен, чтобы
у процессора была работа на некоторое время, прежде чем ему при-
дется остановиться и ждать. Это называется буферизацией, а место,
где устройство хранит прочитанную заранее информацию, назы-
вается буфером. Один из общепринятых видов буферизации — бу-
феризация ввода-вывода. Обычно процессор получает значитель-
ную часть входной информации с перфокарт, а устройство чтения
перфокарт работает во много десятков раз медленнее, чем процес-
сор. Чтобы уравнять скорости, информация с карт передается через
небольшой буфер на диск. Теперь диск играет роль буфера между
центральным процессором и устройством ввода перфокарт. Вместо
того чтобы физически читать карты, центральный процессор чи-
тает их образы с диска. Аналогичным образом можно организовать
буферизацию вывода на печать. Программа буферизации ввода-
вывода — это существенная часть большинства сложных вычис-
лительных систем.
Одна из наиболее интенсивно используемых возможностей, пре-
доставляемых вычислительной системой,— трансляция с языков
программирования с помощью компиляторов, ассемблеров, интер-
претаторов. Этот вид системных программ тоже хорошо известен
читателю. Как и многие другие программы математического обес-
печения, трансляторы с языков программирования должны взаи-
модействовать с вычислительной системой, на которой они рабо-
тают. Места, в которых система и транслятор взаимодействуют
(так называемый интерфейс), требуют тщательной разработки. На-
пример, транслятор должен иметь возможность получать от систе-
мы определенные ресурсы, такие, как память, организованная в виде
файлов, или терминалы с пишущими машинками. Следовательно,
транслятор должен иметь связь с той частью системы, которая уп-
равляет распределением ресурсов. Точно так же, если транслятор
порождает программу в машинном коде, в этой программе должны
строго соблюдаться условия системы, как, например, установлен-
ные в системе правила объединения программ. Со стороны систе-
мы интерфейс должен быть и простым, и гибким, чтобы она могла
взаимодействовать с множеством разнообразных трансляторов.
Вопросам трансляции давно уделяется особое внимание. Раз-
витие этой области достигло уже настолько высокого уровня, что
трансляторы можно приобрести таким же образом, как и аппара-
туру. Существует множество хороших книг как по теоретическим,
так и по практическим вопросам трансляции (например, Мак-Ки-
ман и др. [1970] и Грис [1971]). В нашей книге принято допущение,
что трансляторы либо имеются в нашем распоряжении, либо могут
быть построены в соответствии с установленными требованиями.
Фактически мы относимся к ним так же, как к аппаратуре, которую
можно смонтировать по заданной спецификации. Несмотря на то
что такое допущение в некоторых случаях существенно упрощает
действительное положение вещей, оно приемлемо, когда ставится
цель разобраться в устройстве операционных систем.
Другая важная возможность, которую предоставляют вычисли-
тельные системы,— это средства для работы с большими объектами
информации. Информация разбивается по смыслу на подразделе-
ния, называемые файлами, которые затем хранятся в памяти в со-
ответствии с характером их использования. Доступ к элементам
файла, называемым обычно записями, может осуществляться раз-
нообразными способами в зависимости от структуры файла. Напри-
мер, если файл организован последовательно, то записи читаются
из него в том же порядке, в каком они до этого были записаны (на-
пример, файл на магнитной ленте). Возможность в течение долгого
времени хранить в системе большие блоки данных, имеющие опре-
деленную структуру,— мощный и удобный инструмент. Файлы час-
то размещаются во вспомогательной, а не в оперативной памяти.
Системы управления файлами облегчают разделение информации
между несколькими пользователями. Хорошая структура систем
управления файлами обеспечивает небольшое среднее время до-
ступа к произвольному элементу информации. Поскольку система
управления файлами пользуется ресурсами вычислительной сис-
темы, она должна взаимодействовать с вычислительной системой,
чтобы получать от нее периферийные устройства, оперативную па-
мять и процессорное время. Таким образом, интерфейс между сис-
темой управления файлами и вычислительной системой требует
столь же тщательной разработки, как и рассмотренный нами выше
интерфейс между системой и трансляторами.
Существует множество других программных приспособлений,
которые часто предлагаются пользователям вычислительной сис-
темы. Для некоторых пользователей дополнительные удобства соз-
дают пакеты математических программ, библиотеки статистических
программ, обслуживающие программы сортировки слиянием. Од-
нако включение в математическое обеспечение прикладных про-
грамм обычно считается менее важным, чем включение транслято-
ров или системы управления файлами. Создание прикладных про-
грамм — это предмет численного анализа, статистики и информа-
ционно-поисковых задач и, следовательно, лежит за пределами
темы нашей книги.
1.2. Операционные системы
Операционная система — это та часть математического обеспе-
чения, которая ведает разделением ресурсов. Но не каждая опера-
ционная система ограничивается только средствами, способствую-
щими разделению. При зарождении системного программирования
трансляторы и обслуживающие программы обычно считались час-
тью операционной системы. Хотя в большинстве новейших систем
видна четкая граница между этими средствами и операционной сис-
темой, все еще живы и остатки более широкого взгляда на вещи.
В состав большинства систем входит система управления файлами,
которая значительно сложнее, чем то, что минимально необходимо
для совместного использования устройств ввода-вывода. Системы
управления файлами нужны не столько для разделения устройств
ввода-вывода, сколько для удобства пользователей. Наличие сис-
темы управления файлами в операционной системе обеспечивает
пользователю простой доступ к устройствам ввода-вывода. Тем не
менее у ядра системы (т. е. программного оборудования, которое
непосредственно ведает разделением аппаратного оборудования)
есть функции, которые более или менее неизменны для цесьма раз-
личных машин. В ядре имеются средства, при помощи которых мож-
но осуществлять совместное использование процессоров, опера-
тивной памяти и периферийных устройств. Части операционной
системы, взаимодействующие с пользователями, такие, как систе-
мы пакетной обработки задач или редактирования текстов, исполь-
зуют функции ядра в качестве программной базы примерно таким же
образом, как ядро использует физические устройства в качестве
аппаратной базы. Ядро в основном предоставляет возможности,
пользуясь которыми остальные части операционной системы пре-
доставляют более широкие возможности пользователям. Методы
конструирования и реализации ядра операционной системы со-
ставляют основное содержание нашей книги.
Понятие «пользователь операционной системы» довольно рас-
плывчато. Попросту говоря, пользователь — это тот, кто имеет про-
грамму, которая должна работать на данной системе. Однако эта
программа может обладать самыми разнообразными свойствами.
Ее потребности в процессорном времени, объеме памяти и перифе-
рийных устройствах могут варьироваться в диапазоне от незначи-
тельной доли ресурсов до всей машины целиком. В дальнейшем мы
будем считать, что пользователь — это некто, желающий проде-
лать какую-то вычислительную работу, и что эта работа соответст-
вует возможностям системы.
Независимо от того, какие функции она выполняет, операцион-
ная система должна удовлетворять определенным эксплуатацион-
ным требованиям [Хоар и Перро, 1972]. В частности, система долж-
на обладать следующими качествами:
1. Надежностью. Система должна быть по меньшей мере так
же надежна, как аппаратура, на которой она работает. В случае
ошибки в программном или аппаратном оборудовании система долж-
на обнаружить ошибку и либо попытаться исправить положение,
либо, по крайней мере, постараться свести к минимуму ущерб, на-
несенный этой ошибкой пользователям.
2. Защитой. Пользователь не хочет, чтобы другие пользо-
ватели ему мешали. Поэтому система должна защищать пользова-
телей и от воздействия чужих ошибок, и от попыток злонамеренного
вмешательства.
3. Эффективностью. Обычно операционная система пред-
ставляет собой сложную программу, которая использует значи-
тельную часть аппаратных ресурсов для своих собственных надоб-
ностей. Ресурсы, которые потребляет операционная система, це
поступают в распоряжение пользователей. Следовательно, сама
система должна быть как можно более экономной. Кроме того,
система должна управлять ресурсами пользователей так, чтобы
свести к минимуму время простоя, или, что то же самое, добиться
максимальной загруженности ресурса (т. е. доли времени, когда
ресурс не простаивает).
4. Предсказуемостью. Требования, которые пользователь мо-
жет предъявить к системе, в большинстве случаев непредсказуемы.
В то же время пользователь предпочитает, чтобы обслуживание не
очень сильно менялось в течение продолжительного времени. В част-
ности, вводя программу в машину, пользователь должен иметь
основанное на опыте работы с этой программой приблизительное
представление, когда ему ожидать выдачи результатов.
5. Удобством. Пользователи совместно используют систему
в силу экономической необходимости; у них иногда просто нет вы-
бора. Поскольку операционную систему им навязывают, она должна
быть гибкой и удобной для пользования. В конце концов, пользо-
ватели работают в теснейшем контакте с системой, поэтому при
проектировании системы следует иметь их в виду.
Для того чтобы операционная система могла осуществлять раз-
деление ресурсов и в то же время отвечала перечисленным выше
эксплуатационным требованиям, она должна полностью контро-
лировать распределение ресурсов вычислительной системы. Только
при условии централизованного распределения ресурсов операци-
онная система может добиться равновесия между требованиями
пользователей и техническими ограничениями.
1.3. Распределение ресурсов
Операционная система распределяет ресурсы в соответствии с
нуждами пользователей и возможностями машины и с учетом обыч-
ных требований эффективности и надежности работы. В простых
системах основной ресурс, подлежащий распределению,— это вре-
мя главного процессора. Без него решение задачи не может прод-
винуться вперед. В более сложных и мощных системах и аппарат-
ные устройства, и услуги математического обеспечения можно
считать дефицитными ресурсами, которые распределяются отдельно.
В идеале пользователь должен иметь возможность получать эти
ресурсы, когда бы они ему ни понадобились. К сожалению, это не
всегда выполнимо. Например, бывают моменты, когда общая пот-
ребность пользователей в ресурсах превышает количество имею-
щихся у системы ресурсов. При таких обстоятельствах система
должна найти компромиссное решение и удовлетворить те запросы,
которые она считает более важными. Важность запроса зависит
не только от его срочности для пользователя, но и от того, как удов-
летворение запроса отразится на состоянии системы. Выделение
ресурса одной задаче замедлит обслуживание других задач, пос-
лавших запросы, но зато увеличит загруженность этого ресурса.
Одна из целей системы состоит в том, чтобы эффективно использо-
вать ресурсы, обеспечивая при этом хорошее обслуживание задач.
Сама природа всякой системы такова, что не существует един-
ственного показателя, по которому можно было бы судить о ее каче-
стве. Система по своей сущности объект многомерный. Это обстоятель-
ство усугубляется тем, что система в целом, как правило, предостав-
ляет более сложные возможности, чем те, которые дает любая от-
дельная ее часть. Вероятно, именно это и делает задачу системного
анализа безнадежно трудной. Может быть, единственный плодо-
творный подход состоит в том, чтобы проектировать систему, имея
в виду конкретные поддающиеся количественной оценке факторы,
в том же, что касается неуловимых свойств, положиться на судьбу.
В этом разделе мы изложим некоторые соображения о распределе-
нии основных ресурсов, предоставляемых операционной системой.
1.3.1. Процессорное время
В случае незамысловатой системы вся она целиком распределяет-
ся между задачами как единый ресурс. Пользователь либо распо-
ряжается машиной, либо ждет, когда она будет предоставлена в его
распоряжение. Такую стратегию легко реализовать, но она не обя-
зательно будет эффективно использовать оборудование. Програм-
ма, находящаяся в счете, может не пользоваться никакими перифе-
рийными устройствами. Ясно, что те ресурсы, которые работающая
программа не использует, простаивают, и, таким образом, их за-
груженность уменьшается. Это противоречие можно несколько
сгладить, если использовать присущую аппаратным устройствам
способность работать параллельно.
Поскольку периферийные устройства могут работать параллель-
но с главным процессором, можно сделать так, чтобы одна програм-
ма выполняла операцию ввода-вывода, пока другая программа за-
нимает главный процессор. Хотя реализовать все элементы такого
подхода сложно, у него все-таки есть и преимущество: каждое
устройство используется более интенсивно. Однако для того, чтобы
обратиться к устройству ввода-вывода, программа должна в это
время занимать процессор, поэтому распределение процессорного
времени становится трудной задачей. Например, выделение про-
цессора программе, которой не нужны периферийные устройства,
может значительно увеличить время простоя этих устройств. С дру-
гой стороны, если стараться оптимизировать использование всех
ресурсов, это может привести к невыносимо медленному обслужи-
ванию некоторых программ, в особенности тех, которым не нужны
периферийные устройства. Такие дилеммы встречаются часто, и раз-
решить их нелегко. Способы распределения процессоров в системе,
использующей параллелизм устройств, мы рассмотрим в гл. 3.
1.3.2. Управление памятью
Управление памятью тесно связано с распределением процес-
сора. Программы могут работать только в то время, когда они на-
ходятся в оперативной памяти, но не следует их держать там, если
надежда получить процессор невелика. Иначе получится, что па-
мять, которую они занимают, пропадает зря. Оперативная память —
дорогой ресурс, и, по-видимому, останется относительно дорогим
в обозримом будущем. Поэтому система расходует значительную
часть времени на то, чтобы расположить информацию рационально,
стараясь держать полезные программы в оперативной памяти и
уничтожать промежутки между программами.
Для того чтобы ликвидировать «дыры» в памяти между програм-
мами, система может предпринять перемещение программ. Оно со-
стоит в том, что программы передвигаются в оперативной памяти
таким образом, чтобы уменьшился объем бесполезно расходуемой
памяти. Перемещение программ можно существенно облегчить,
если применять специальные стратегии организации памяти. Эти
стратегии позволяют операционной системе весьма гибко регули-
ровать обмен информацией между оперативной и вспомогательной
памятью. Однако такие стратегии обычно требуют специального ап-
паратного оборудования и приводят иногда к довольно большим
издержкам. Чтобы расходы на дополнительные усложнения в
программе распределения памяти были оправданными, любое суще-
ственное усовершенствование в использовании памяти следует ре-
ализовывать на стандартных схемах оборудования. К сожалению,
очень трудно подсчитать чистый выигрыш, который сложная стра-
тегия распределения памяти приносит системе в целом. Несмотря
на большое количество исследований по стратегиям распределе-
ния памяти, оптимальные методы по-прежнему остаются сложными
для анализа и для реализации.
Способы распределения памяти будут изложены и проанализи-
рованы в гл. 4 и 5 соответственно.
1.3.3. Устройства ввода-вывода
Методы распределения устройств ввода-вывода и соответствую-
щих контроллеров г) и каналов различны и зависят от скорости
устройства. Например, устройства чтения перфокарт, печатающие
и лентопротяжные устройства связаны в каждый момент с одной
задачей. Задача пользуется периферийным устройством столько
времени, сколько ей нужно, а затем отказывается от него. Уст-
ройства с быстрым произвольным доступом, такие, как барабаны и
диски, можно совместно использовать по принципу «операция за
операцией». Иначе говоря, вместо того чтобы отдать устройство
одной задаче на продолжительное время, нескольким задачам раз-
решается использовать устройство попеременно. Если две задачи
пытаются выполнить операцию ввода-вывода на одном устройстве
одновременно, то получится задержка. Но поскольку эти устрой-
ства работают быстро, задержка терпима. С устройством чтения
х) Контроллер — устройство, согласующее представление информации на
входах и выходах центрального процессора и внешнего устройства.— Прим. ред.
перфокарт или лентопротяжным устройством такая форма работы
невозможна, потому что физическая природа устройства требует
его разгрузки при переключении от одной задачи к другой.
Подход к распределению устройств оказывает существенное вли-
яние как на правильность, так и на эффективность работы. Напри-
мер, если в системе имеется одно читающее и одно печатающее
устройство, неверная тактика распределения может привести к не-
предвиденной остановке. Если пользователь А занимает читающее
устройство и ему, чтобы закончить работу, нужно печатающее
устройство, а пользователь В занимает печатающее устройство и
ему, чтобы закончить работу, нужно читающее устройство, то и
А, и В будут сидеть и ждать вечно (или до тех пор, пока кто-нибудь
из них не проявит способность к предвидению и не освободит свой
ресурс, чтобы дать другому возможность закончить работу). Про-
грамма распределения ресурсов должна предотвращать такие ситуа-
ции.
Стратегия распределения влияет и на эффективность исполь-
зования устройств. Рассмотрим, например, систему с тремя ленто-
протяжными устройствами, и пусть задание А запрашивает два, а
задание В — три таких устройства. Если два устройства свободны,
а одно еще занято, иногда лучше подождать, пока оно освободится,
чтобы удовлетворить запрос задания В, чем надолго отдать два
устройства заданию А. Так, если задание В уже занимает какой-то
дорогой ресурс (например, другое периферийное устройство или
много места в оперативной памяти), то может оказаться целесооб-
разнее поскорее протолкнуть его через систему, даже ценой про-
стоя двух лентопротяжных устройств. Такие решения по плани-
рованию работы, возможно противоречащие здравому смыслу, если
рассматривать ограниченную ситуацию, в действительности повы-
шают общую производительность системы.
Эффективное распределение периферийных устройств трудно
реализовать по двум причинам. Во-первых, с помощью существую-
щих математических методов нельзя провести необходимые исследо-
вания и отыскать оптимальные способы распределения нескольких
различных типов устройств. Известно много способов для част-
ных случаев, но уравновешивание системы, имеющей много ресур-
сов, все еще остается наполовину наукой, а наполовину искусст-
вом. Во-вторых, эффективность стратегии распределения данной
системы трудно измерить. Знание, что производительность плохая,
не помогает выделить конкретные трудные случаи. Дело в том, что,
к сожалению, большинство современных методов управления сис-
темой не позволяет указать конкретные причины плохой произво-
дительности; можно оценить только общие внешние проявления не-
правильного распределения. Если же при оценке учитывать и влия-
ние взаимодействия с оперативной памятью и центральным процес-
сором, то аналитические и эмпирические методы оказываются еще
менее перспективными. Хотя способы эффективного распределения
процессоров или памяти без учета других ресурсов известны, труд-
но предсказать производительность сложной системы, в которой эти
способы распределения объединены.
Методы разделения устройств ввода-вывода, контроллеров и
каналов сильно зависят от устройств. Одна из возможных схем ор-
ганизации разделения будет рассмотрена в гл. 6.
1.3.4. Программные ресурсы
В хорошей операционной системе общего назначения часто име-
ются обширная система прикладных программ и библиотеки прог-
рамм пользователей. Будучи ресурсами, подлежащими распределе-
нию, эти библиотеки имеют много общего с аппаратными ресурсами.
Совместное использование компиляторов, интерпретаторов и спе-
циальных обслуживающих программ, таких, как редактор текстов
или программа сортировки слиянием, можно организовать, если
эти программы допускают параллельное использование. Программа
допускает параллельное использование х), если у нее рабочая часть
полностью отделена от данных и операции записи в память приме-
няются только к разделу данных. Такой программой могут одновре-
менно пользоваться несколько пользователей. Для этого каждому
пользователю выделяется личный экземпляр раздела данных, а с
единственным экземпляром рабочей части все пользователи могут
работать в режиме разделения. Если программа не допускает парал-
лельного использования, то каждый ее экземпляр может быть вы-
делен в каждый момент только одному пользователю, так же как
любое аппаратное устройство. Разделение программного оборудо-
вания допускает больше гибкости, чем разделение аппаратного
оборудования, так как дополнительные экземпляры первого в слу-
чае необходимости можно получить за приемлемую цену. Что ка-
сается аппаратного оборудования, то обычно приходится обхо-
диться тем, которое есть. Говоря о разделении программного обо-
рудования, следует рассмотреть те же вопросы эффективности и
корректности, что и в случае аппаратного оборудования.
1.4. Супервизор
Традиционный подход при проектировании операционной сис-
темы состоит в том, что множество процессов, выполняющих
основные функции системы, подчиняются главной программе, на-
зываемой супервизором. Осуществляя централизованное управление,
х) В оригинале «reentrant code». В литературе на русском языке также упо-
требляется термин «реентерабельная программа».— Прим, перев.
супервизор связывает воедино остальные части системы. Он ор-
ганизует совместную работу программ, устанавливая привилегии или
иногда назначая наказания. Он обеспечивает средства связи и син-
хронизации между процессами и физическими устройствами. Обыч-
но и сообщения, передаваемые от процесса к процессу, и запуск,
и окончание работы устройств, и сигналы от оборудования обраба-
тываются супервизором. (В некоторых системах на работу супер-
визора приходится добрая половина системного времени.) Тем не
менее не существует веских оснований для того, чтобы делать супер-
визор очень большим. У децентрализованной организации могут
быть свои преимущества, благодаря которым возрастет произво-
дительность системы.
Супервизор обычно управляет распределением всех ресурсов
и услуг системы между пользователями. Когда какая-то часть сис-
темы, выполняющая определенную функцию, например трансля-
тор или система управления файлами, становится слишком боль-
шой, ее выделяют из супервизора. Но, несмотря на то что она
теперь находится вне супервизора, она по-прежнему обязана
выполнять все, что потребует супервизор. В большинстве сис-
тем программа должна уведомить супервизор о том, что она поль-
зуется каким-то из ресурсов системы, даже если эта программа
не входит непосредственно в супервизор. Поэтому, даже если
супервизор маленький, за ним сохраняется обязанность контро-
лировать почти всю систему.
1.4.1. Функции супервизора
Главная цель операционной системы — сделать возможным раз-
деление. Для того чтобы это делалось эффективно, общая коорди-
нация возложена на супервизор. Функции супервизора можно
грубо разделить на четыре области: контроль и управление, орга-
низация связей, защита и ограничение, обслуживание [Мили,
1967].
1.4.1.1. Контроль и управление
В обязанности супервизора входит устанавливать последователь-
ность и контролировать выполнение заданий в системе. Для обработ-
ки заданий служат и планирование порядка выполнения заданий, и
учет потребления ими ресурсов, и интерпретация языка управления
заданиями. Эти функции можно реализовать независимо от супер-
визора или подчинить ему. Пользователь описывает свои требования
на некотором языке управления заданиями. Супервизор интерпре-
тирует эти требования и сообщает различным программам, распре-
деляющим ресурсы, какие ресурсы и задачи х) запрошены зада-
г) Задача — это, с точки зрения операционной системы, элементарное, неде-
лимое действие, а задание — совокупность задач.— Прим, перев.
нием. Распределители ресурсов обслуживают запросы, возможно,
в порядке их приоритетов. Программа учета запоминает количество
потребленных пользователем ресурсов и записывает их в долг соот-
ветствующей программе пользователя, с тем чтобы в дальнейшем
предъявить счет.
1.4.1.2. Организация связи
В супервизоре предусмотрены средства связи между различными
программами. Когда две независимые программы, такие, как фай-
ловая система и программа управления памятью, хотят связаться
друг с другом, они должны попросить супервизор установить кон-
такт. После того как супервизор установит первоначальный кон-
такт, программам разрешается передавать друг другу сообщения
принятым в данной системе путем, например с помощью «писем» и
общего «почтового ящика». Первоначально связь должна быть уста-
новлена через супервизор, потому что только ему доступны сведе-
ния о том, где размещаются независимые программы и как с ними
можно связаться. Доступная только супервизору информация
позволяет ему выполнять и другие действия, касающиеся связей,
например установление контактов между системными программами
и программами пользователей. Господство супервизора во многом
происходит от того, что он просто знает больше любого своего
клиента.
1.4.1.3. Защита и ограничения
Для того чтобы гарантировать, что работа пройдет гладко, супер-
визор должен наложить некоторые ограничения как на систему,
так и на пользователей. Имеется ряд программ, обрабатывающих
сигналы аппаратуры, особенно отклонения от нормальных условий.
Когда поступает сигнал об ошибке (обычно это прерывание), су-
первизор должен принять решение задержать или даже выкинуть
задание. Ограничения должны налагаться на время работы програм-
мы и количество выдаваемых ею результатов. Супервизор может
также организовывать систему защиты с помощью специальных
«паролей». Доступ к защищенным ресурсам разрешается только по
соответствующему паролю. Предполагается, что пароль нельзя
подделать.
Ввиду того что под контролем супервизора сосредоточено боль-
шое количество информации, супервизор представляет собой очень
чувствительную часть системы. Следовательно, супервизор должен
относиться с подозрением и к остальным частям системы, и к поль-
зователям, чтобы избегать случайного или злонамеренного вторже-
ния в его собственные области памяти. Чтобы сделать возможной
защиту супервизора, в некоторых системах существует два типа
режимов работы: режим супервизора и рабочий. Специальные опе-
рации, такие, как запуск ввода-вывода или обращение к особым
ячейкам оперативной памяти, могут выполняться только в режиме
супервизора. Благодаря этой предосторожности супервизор об-
ладает особой властью над привилегированными частями системы
и программами пользователей. Супервизор может защитить себя,
храня жизненно важную информацию в защищенной области па-
мяти, доступной только в режиме супервизора. Такое устройство
оборудования предохраняет супервизор от постороннего вмешатель-
ства.
1.4.1.4. Обслуживающие программы
Помимо распределения ресурсов супервизор сам выполняет
некоторые функции системы. В нем имеется набор обслуживающих
программ для аварийных сбросов, для доступа к библиотекам про-
грамм, для обработки сообщений от программ, работающих в опе-
ративном режиме. Внутри супервизора часто находятся область
памяти, предназначенная для организации связей, и таблицы сис-
темы защиты. Кроме того, в обязанности супервизора могут вхо-
дить выполнение инструкций языка управления заданиями, роль
интерфейса между системами и операторским пультом, учет. Когда
требуется выполнить более сложные действия, супервизор обычно
вызывает специальные обрабатывающие программы.
1.4.2. Оценка централизованного управления
Идеология централизации ключевых функций системы под кон-
тролем супервизора имеет свои преимущества и недостатки. Одно
из преимуществ централизации — простая реализация защиты.
Режим супервизора дает возможность отделить какие-то части
системы от пользователей. Второе преимущество связано с простотой
организации. С точки зренйя разработки идеологии легче сосре-
доточить важнейшие системные функции в подчинении у супер-
визора, чем распространить их по всей системе. Лучше всего такой
подход оправдывает себя, когда супервизор делают очень малень-
ким, поскольку в этом случае управление системой сосредоточи-
вается внутри области, границы которой легко определить. К со-
жалению, очень велико искушение включить в супервизор много
функций, а при этом теряется преимущество различия между супер-
визором и операционной системой.
Однако у централизованного супервизора есть и существенные
недостатки. Программам не разрешается устанавливать связи друг
с другом самостоятельно. Следовательно, каждый раз, когда слу-
чается что-то важное, нужно обращаться к супервизору. Когда много
программ пытаются одновременно установить связь, лишь немно-
гим удается пробиться к супервизору. Это пример узкого места:
большое количество информации надо пропустить через канал, име-
ющий ограниченную пропускную способность. Обращения к супер-
визору и услуги, которые он предоставляет, порождают наклад-
ные расходы. Поскольку обращения часты, супервизор может стать
одним из главных (или даже самым главным) узким местом в системе.
К соображениям относительно эффективности можно добавить,
что соединение многих функций в супервизоре затрудняет внесе-
ние в них изменений. Функции могут быть взаимнозависимыми, что
затрудняет обособление отдельных функций. Изменение в одной
части супервизора отражается на всех остальных связанных с ней
частях. Так небольшое изменение может вылиться в капитальную
реконструкцию супервизора.
Несмотря на эти трудности, проведенные недавно исследования
свидетельствуют в пользу применения супервизора или структуры
объединенных супервизорных программ [Бринч Хансен, 1970].
Например, своя программа может быть связана с каждым из основ-
ных аппаратных ресурсов: с оперативной памятью, дисками, чи-
тающими и печатающими устройствами и терминалами. При сов-
местной работе такие программы вместе выполняют те же функции,
что и супервизор. Введение модульного принципа распределения
функций по отдельным программам уменьшает сложность каждой
части, однако при этом увеличивается количество необходимых
связей между частями. И с централизованным супервизором, и с
использованием методов объединенных супервизорных программ
были построены удачные системы. Разнообразные точки зрения на
структуру систем будут рассмотрены в гл. 2, 8 и 9.
1.5. Заключение
Функции операционной системы в вычислительной системе мож-
но сравнить с функциями администрации на предприятии. И та,
и другая выполняют важную работу, что приводит к определенным
накладным расходам. Административные служащие обязаны за-
ниматься организацией полезной работы, которая выполняется
предприятием, и распределять ресурсы предприятия между рабо-
тающими группами. Даже с приходом автоматизации в промышлен-
ность административная работа остается необходимой. То же самое
справедливо и для вычислительных систем: хотя аппаратное обо-
рудование становится способным выполнять более сложные задачи,
нужда в операционной системе не ослабевает. Однако конкретные
элементы выполняемой операционной системой работы могут зна-
чительно измениться.
Ожидается, что в не очень далеком будущем многие из принад-
лежащих к нижнему уровню программного оборудования программ,
управляющих некоторыми ресурсами, в частности памятью и пери-
ферийными устройствами, будут заменяться аппаратным обору-
дованием. Но это не означает, что рассматриваемый нами предмет
отомрет. Напротив, задача разделения ресурсов будет стоять перед
нами всегда. Хотя конкретные технические особенности ресурсов
могут измениться, основные методы разделения ресурсов, по-види-
мому, еще долго будут находить широкое применение во многих
отраслях проектирования вычислительных систем.
Задания
1.1. Составьте список запоминающих устройств и охарактеризуйте
каждое сточки зрения скорости и стоимости запоминания одного би-
та. Дополните эту таблицу данными, соответствующими 1950,
1955, 1960, 1965 и 1970 годам. Прокомментируйте тенденции,
которые выявятся в вашей таблице.
1.2. К вычислительной машине можно подключить много устройств
ввода-вывода. Составьте список различных устройств ввода-вывода
с основными характеристиками, включая скорость и стоимость
передачи одного символа. Сравните специальные устройства, та-
кие, как устройство вывода на микрофильм или устройства, чита-
ющие напечатанный или написанный магнитными чернилами текст,
с обычными, такими, как устройства чтения перфокарт и вывода на
печать.
КЗ. Рассмотрим мини-машину, которая служит устройством спе-
циального назначения, например устройство, которое уплотняет
информацию, полученную непосредственно от пользователя, для
передачи в систему, или сетевой интерфейс. Каковы обязатель-
ные функции операционной системы, обслуживающей такую систе-
му? Какие действия, выполнимые в системах общего назначения,
становятся здесь маловажными?
1.4. В чем разница между каналом и современной мини-машиной?
Может ли мини-машина служить каналом? Каким мог бы быть в
этом случае интерфейс между нею и центральной машиной?
1.5. Составьте список оборудования какой-нибудь конкретной вы-
числительной системы с ценами всех устройств. Сравните цены
процессора, оперативной памяти и периферийных устройств. Ка-
кова доля оборудования в общем бюджете вычислительного центра?
1.6. Понаблюдайте за оператором, обслуживающим машину в вашем
вычислительном центре. Составьте описание обязанностей опера-
тора. Будь вы проектировщиком системы, в какой степени полага-
лись бы вы на оператора? Приведите примеры решений, которые
должна принимать сама система. К какого рода работам операторы
подготовлены лучше всего?
1.7. Представьте себе, что вам предложено спроектировать операци-
онные системы для ряда машин с возрастающими размерами и
скоростью, причем каждая предыдущая машина ряда совместима
со следующей. Будете ли вы проектировать одну операционную
систему или по операционной системе для каждой машины? Поду-
майте о преимуществах и недостатках обоих подходов, которые
проявятся при сбыте, эксплуатации, проектировании и реализации
таких систем.
1.8. Представьте себе вычислительную систему, предназначенную
исключительно для решения вычислительных прикладных задач
с небольшими потребностями во вводе-выводе. Как отразится та-
кой подбор оборудования на архитектуре вычислительной системы
и возможностях операционной системы?
1.9. Допустим, вам предложено спроектировать операционную сис-
тему для новой мини-машины. Составьте список возможностей,
которые бы вы включили в систему. Упорядочьте их по убыванию
важности.
1.10. По закону Гроша, эффективность вычислительной системы
пропорциональна квадрату ее стоимости [Шарп, 1969]. Этот аргу-
мент был главным основанием для создания больших централизо-
ванных вычислительных систем. Попробуйте проверить примени-
мость закона Гроша к центральным процессорам, вычислительным
машинам, мини-машинам, оборудованию для связи и т. п.
1.11. Предложение и спрос товаров контролируются системами
образования цен. Рассмотрите относительные достоинства различ-
ных схем образования цен на услуги вычислительной системы.
Выберите такую схему, которая была бы справедливой, взаимно вы-
годной и не требовала бы больших затрат на свое осуществление.
Глава 2
ПРОЦЕССЫ
2.1. Введение
Тема этой главы — определение и свойства процесса, т. е. ос-
новной единицы работы в операционной системе. Рассмотрим сна-
чала знакомый нам тип работы — последовательную программу.
Большую последовательную программу, написанную на языке типа
АЛГОЛ или PL/I, можно подразделять на меньшие последователь-
ные программы, называемые процедурами. Если рекурсия исключе-
на, то процедура никогда не может приводиться в действие несколь-
кими обращениями одновременно. Следовательно, любой работе,
которая выполняется в данный момент, однозначно соответствует
действующая процедура. Однако в операционных системах эта
простая связь между выполняемыми работами и процедурами утра-
чена. Одна процедура может работать одновременно в нескольких
частях системы. Например, несколько каналов, связанных с дис-
ками, могут разделять одну процедуру ввода. И наоборот, функция,
которая по смыслу представляет собой единую операцию, напри-
мер «ввод», может каждый раз по ходу работы использовать одну
или несколько различных процедур. Если в задании сказано «чи-
тать карту», система предпринимает различные действия в зави-
симости от того, где находится следующая карта. Она может быть
уже в оперативной памяти, или она может находиться на диске,
или, возможно, ее следует физически прочесть при помощи устрой-
ства для чтения перфокарт. В некоторых случаях команда «читать
карту» может оказаться многошаговой операцией, включающей
шаги, которые выполняются параллельно. Таким образом, дан-
ной рабочей задаче может соответствовать одновременно более од-
ной процедуры, а единственная процедура может действовать одно-
временно более чем в одной рабочей задаче. Взаимно однозначного
соответствия между процедурами и выполняемыми работами, ка-
кое существует в языках для последовательного программирования,
в операционных системах нет. Поэтому понятия процедуры и ра-
боты нельзя считать эквивалентными.
Внутри операционной системы работы не обязательно выполня-
ются последовательно. И центральный процессор, и каналы, и уст-
ройства — все работает параллельно. Естественно, что эта парал-
лельность отражается и на программном оборудовании. Как пра-
вило, операционная система выполняет множество работ, которые
продвигаются вперед почти независимо, как, например, ввод, вы-
вод и деятельность центрального процессора. Понятие процесса —
это формализация идеи «независимой работы». Процессы представ-
ляют собой удобную модель, помогающую уяснить, что происхо-
дит внутри операционной системы. Внимательное изучение парал-
лельности, заложенной уже в самой машине, лучше всего помогает
понять причину изобретения параллельных процессов.
2. 1.1. Параллельность в системах
аппаратного оборудования
В аппаратном оборудовании уже на уровне разрядов операции
почти всегда выполняются параллельно. Обычный способ создания
более быстрых арифметических устройств, таких, как сумматоры
и умножители, состоит в том, чтобы увеличить количество работы,
которая может выполняться параллельно. Для такого подхода есть
важная причина. Существующая технология производства электрон-
ных цифровых устройств такова, что скорости отдельных компонент
приближаются к своим физическим пределам. Устройства работают
со скоростью порядка десятых долей наносекунды, а свет за одну
наносекунду проходит расстояние около тридцати сантиметров.
Дальнейшая миниатюризация еще несколько увеличит скорость
устройств. Однако более важные усовершенствования в области
увеличения мощности машин, вероятно, будут обусловлены увели-
чением параллелизма.
Периферийные устройства и связанные с ними каналы работают
параллельно с блоком центрального процессора. В самом централь-
ном процессоре тоже можно широко использовать параллелизм
аппаратного оборудования. Производительность многих машин
была повышена путем увеличения числа процессов (например,
ILLIAC IV). В системе аппаратного оборудования с несколькими
арифметическими процессорами и большим числом каналов, кото-
рые работают все одновременно, организация работ, связанных с
этими устройствами, становится сложной задачей. Организовать
же эти работы эффективно еще сложнее.
Один пользователь обычно загружает устройства системы не-
равномерно. Если он в данный момент вводит или выводит много
информации, то, вероятно, не очень долго занимает арифметичес-
кое устройство. И наоборот, если он делает много вычислительной
работы, то, по-видимому, не занимает в это время устройства ввода-
вывода. Разрешая нескольким пользователям работать одновре-
менно, система получает больше возможностей полностью загру-
зить оборудование. Пока один пользователь печатает, а другой чи-
тает, третий может выполнять вычисления на центральном процес-
соре. Поэтому в дополнение к множеству аппаратных устройств,
работающих параллельно, может быть еще несколько заданий поль-
зователей, которые выполняются параллельно.
22. Параллельность в системах
программного оборудования
Задания пользователей, выполняемые параллельно, вообще не
должны учитывать существование друг друга. Когда какое-то за-
дание отдает приказ печатать, его не касается, что другое задание
в это время читает карты. Подобным образом работают и аппарат-
ные устройства. Печатающее устройство обычно не знает о сущест-
вовании читающего. Чтобы получить адекватную модель такого
функционирования, нужно ввести единицу работы, которая бы от-
ражала эту параллельность, а это и есть процесс. Поскольку работы
выполняются независимо, нужно, чтобы представляющие их про-
цессы были независимыми. Кроме того, поскольку устройства ра-
ботают с различными скоростями, то должны допускаться произ-
вольные соотношения скоростей выполнения процессов. Итак, при
изучении вычислительных систем мы выделили несколько свойств
процессов: процессы — это независимые работы, которые выполня-
ются параллельно и с различными скоростями.
Работам иногда все-таки нужно обмениваться информацией.
В той мере, в какой работам необходимо общаться друг с другом, они
не вполне независимы. В процессах, которые служат для модели-
рования работ, должна быть отражена эта возможность общения.
Если бы процессам было разрешено передавать сообщения произ-
вольным образом, то было бы трудно разбираться в их сложных вза-
имодействиях. Поэтому общение между процессами разрешается
только по четким, строго определенным схемам. Методы организа-
ции общения между процессами будут описаны в следующих раз-
делах.
Несмотря на то что, как было показано выше, параллельность
имеется в работе частей как аппаратного, так и программного обо-
рудования, программы обычно последовательны. Впрочем, так
бывает не всегда. Существуют языки программирования, которые
позволяют описывать параллельные вычисления. Тем не менее чело-
веческий разум, кажется, лучше приспособлен к тому, чтобы справ-
ляться с последовательными программами. Поэтому мы здесь будем
считать процессы последовательными. То есть операции внутри
процесса выполняются в строго определенной последовательности.
На интуитивном уровне можно мыслить себе процесс как выполне-
ние программы на АЛГОЛе. В последующих разделах мы будем
вместо термина «последовательный процесс» для краткости употреб-
лять слово «процесс», не делая больше никаких пояснений.
2.2. Определение процесса
Понятие «процесс» встречается во многих публикациях. Это,
вероятно, наиболее часто употребляемый и наименее точно опре-
деленный термин из области операционных систем. Говоря нестрого,
процесс можно представить себе как группу ячеек памяти, содержи-
мое которых меняется по определенным правилам. В машине эти
правила обычно описываются программой, которую интерпрети-
рует процессор. Хотя замысел, лежащий в основе этого понятия,
ясен, определения давались весьма разнообразные. Почти в каж-
дой новой системе или модели системы этот термин переопределялся
и ему придавалось несколько иное дополнительное значение. В ОС/
360 термин «задача» употребляется и определяется как «основная
единица, подчиняющаяся управляющей программе при мульти-
программном режиме» [IBM, 1965]. Зальтцер [1966] утверждает,
что «процесс — это программа, выполняемая псевдопроцессором».
Дейкстра [1968b] определяет последовательный процесс как то,
что происходит во время выполнения последовательной программы
на машине. Хорнинг и Ренделл [1973] построили формальное опре-
деление понятия процесса. Для внесения ясности в это понятие
мы предлагаем формальную модель процесса, очень сходную с упо-
мянутой моделью Хорнинга и Ренделла [1973].
Пусть Х={х0, %!,..., xN, . . .} — это набор, быть может бес-
конечный, переменных, характеризующих состояние, называемый
набором переменных состояния. Состояние описывается заданием
значений всех элементов, входящих в набор переменных состояния.
Пространство состояний для данного набора переменных состоя-
ния — это множество состояний, которые может принимать этот
набор переменных. Действие — это присваивание значений неко-
торым из переменных данного набора. Последовательность состоя-
ний, принадлежащих пространству состояний, называется рабо-
той. Один из способов произвести работу состоит в последователь-
ном применении различных действий. Каждое действие порождает
новое состояние, а получаемая последовательность состояний, по
определению, есть работа. Функция действия — это функция, ко-
торая отображает состояния в действия. Функция действия может
также порождать работу по заданному начальному состоянию.
Она просто описывает действие, которое надо применить к каждому
очередному состоянию, а это действие порождает новое состояние.
Функция действия перерабатывает новые состояния до бесконеч-
ности, получая таким образом последовательность состояний. На
содержательном уровне набор переменных — это память, состоя-
ние— это содержимое памяти, а функция действия—это программа.
Теперь мы можем определить процесс как пространство состоя-
ний, функцию действия в этом пространстве и некоторые особые
элементы пространства состояний, называемые начальными состоя-
ниями. Рассмотрим процесс Р, имеющий две переменные: х и у.
Работу процесса Р можно описать последовательностью состоя-
ний: {(2, 1), (4, 2), (6, 3), (8, 4), . . . , (2 I, /),...}. Работу процес-
са Р можно также описать, указав пространство состояний
{(/, /), где i и / — натуральные числа}, одно из начальных состоя-
ний (2, 1) и функцию действия, которая над всеми состояниями
производит действие (%, у)-> (%+2, у-Н).
Каждое состояние процесса — это «моментальный снимок» хода
работы, которую выполняет процесс. Пусть программа вместе со
своими переменными находится в оперативной памяти. Можно
проследить за выполнением этой программы, наблюдая за связан-
ными с ней ячейками и регистрами. В любой заданный момент каж-
дая ячейка памяти будет содержать определенную величину. По-
ложение, складывающееся в ходе выполнения программы, описыва-
ется значениями, которые находятся во всех ее ячейках в данный
момент. Отсюда и возникла идея состояния. Последовательность
состояний описывает ход работы программы в данной среде. Про-
грамма, или функция действия, имеющая начальное состояние,—
это просто другой способ описания той же последовательности со-
стояний.
Некоторым наблюдателям отдельные состояния покажутся до-
вольно неинтересными. Например, при обращении к процедуре,
с точки зрения обращающейся программы, интересны состояния в
момент обращения и в момент возврата, причем особенно важны
значения параметров. Большинство «внутренних» состояний про-
цедуры не заслуживает особого внимания, поскольку для обращаю-
щейся программы обычно существенны только результаты обраще-
ния к процедуре. Подобным же образом только некоторые из пере-
менных представляют особый интерес, а именно те, в которых
получаются результаты счета. Обе эти идеи легко выразить на фор-
мальном языке, рассматривая только подмножества состояний и пе-
ременных состояния.
В описанной выше модели проявляются те свойства процессов,
о которых говорилось в предыдущем разделе. Например, было ска-
зано, что процессы в принципе независимы. Ясно, что если у двух
процессов отдельные наборы переменных состояния, то они не могут
взаимодействовать. Общение между процессами моделируется раз-
деляемыми переменными. Мы уже отмечали, что несколько процес-
сов могут выполнять одну и ту же программу. Это соответствует
эквивалентным функциям действия, которые применяются к раз-
ным наборам переменных. В сущности, большинство идей, относя-
щихся к процессам, можно сформулировать в терминах модели
Хорнинга и Ренделла. Однако для нас здесь важен тот факт, что
формальные определения существуют. То, что оставшаяся часть
этой главы носит весьма неформальный характер, не следует истол-
ковывать как недостаточную четкость идей. Напротив, четкие идеи
излагаются неформально главным образом для удобства объясне-
ния.
Несмотря на то что процессы были формально определены как
абстрактные понятия, они служат моделью реальных объектов,
содержащихся в операционных системах. Функции действия и пе-
ременные состояния соответствуют процедурам и ячейкам памяти.
В следующем разделе мы рассмотрим один из путей реализации
процессов как частей программного оборудования.
2.3. Реализация процессов
Изложенный ниже подход к реализации идеи процессов хотя и
не воспроизводит в точности никакую конкретную систему, но
очень сходен с реализацией процессов во многих системах, таких,
как RC4000, THE, проект SUE и «Венера» (см. гл. 10). В реальной
системе процесс осуществляет выполнение одной или нескольких
процедур на физическом процессоре, имеющемся в аппаратном обо-
рудовании. Каждый программный процесс однозначно определя-
ется некоторой информационной структурой, называемой дескрип-
тором процесса. В типичной системе дескриптор процесса состоит
из
1) переменной состояния, которая определяет положение про-
цесса (например, «готов к работе», «работающий», «заблокирован»);
2) защищенной области памяти, в которой хранятся текущие
значения регистров, когда процесс прерывается, не закончив ра-
боты;
3) информации о ресурсах, которыми процесс владеет или имеет
право пользоваться.
Помимо всего прочего, в дескрипторе процесса может быть от-
ведено место для организации общения с другими процессами. Раз-
бор общения между процессами отложим до следующих разделов.
В разд. 2.2 мы определили процесс как абстрактную единицу
работы, утверждая, что это удобно для описания деятельности
операционной системы. Машинное представление процесса состоит
из дескриптора и области памяти. Очень важно различать абстракт-
ный и программный процессы. Обычно программный процесс —
это и абстрактный процесс, а обратное верно далеко не всегда. Да-
лее в этом разделе мы будем абстрактные процессы явно именовать
абстрактными. Поскольку в нашей книге в центре обсуждения будут
находиться почти исключительно одни программные процессы, тер-
мин «процесс» будет относиться только к программным процессам.
Дескриптор и область памяти, из которых состоит программный
процесс, должны быть каким-то образом выделены из имеющих-
ся у машины ресурсов. Есть два подхода к образованию програм-
мных процессов. Можно построить систему с фиксированным числом
программных процессов, которые существуют всегда. В таком слу-
чае программные процессы образуются одновременно с системой.
Чтобы выполнить некоторую работу, нужно только получить в свое
распоряжение один из существующих программных процессов. Аб-
страктных процессов может быть больше, чем имеется програм-
мных процессов. Поэтому абстрактному процессу, возможно, при-
дется ожидать, когда ему будет предоставлен программный процесс,
чтобы он мог выполнить надлежащую работу. Другой путь может
состоять в том, что в системе предусматривают механизм, который
образует и уничтожает программные процессы, когда поступает
соответствующий запрос. Этот механизм, который сам програм-
мным процессом не является, дает системе возможность манипули-
ровать программными процессами; он называется «стержнем».
Далее в этом разделе мы будем считать, что существует стержень и
что в системе уже имеется один или несколько программных про-
цессов.
Процессы могут вызывать образование или уничтожение других
процессов. Так, один процесс может потребовать, чтобы стержень
образовал другой процесс. Стержень заводит дескриптор нового
процесса, выделяет для процессов память и сообщает о завершении
этой деятельности образующему процессу. Тогда образующий про-
цесс помещает в память нового процесса программу (т. е. пред-
ставление некоторой функции действия). В стержне предусмотрена
команда «запустить», которая выделяет процессу процессор. Обра-
зующий процесс может запустить выполнение созданного процесса,
обратившись к операции запуска с образованным процессом в ка-
честве параметра. Аналогично команда «остановить» отбирает у
процесса процессор, а команда «уничтожить» отбирает дескрип-
тор и ресурсы.
Много процессов могут существовать и в системе с единственным
процессором. Стержень дает каждому процессу попользоваться
процессором в подходящий для этого момент. Например, если имеет-
ся десять процессов, стержень может давать каждому процессу
по одной десятой каждой секунды работы процессора. Каждый про-
цесс ведет себя так, как будто у него есть собственный центральный
процессор (хотя и медленный). В действительности же все процессы
разделяют один процессор. Запуск и остановка процессов реали-
зуются как разрешение и отмена разрешения на доступ к разде-
ляемому процессору.
Процессы могут существовать как не связанные друг с другом
единицы или могут быть связаны особыми отношениями, образуя
структуры. Если система не предусматривает такой структурной
организации, то одна из ее частей, обычно супервизор, обязана по
мере надобности образовывать процессы. Когда появляется задача,
супервизор образует процесс для выполнения этой задачи. Когда
задача выполнена, процесс уничтожается. Таким образом, все про-
цессы «равны» в рамках системной структуры. Каждый образу-
ется и уничтожаетСлЯ супервизором. В системе, имеющей более слож-
ную структуру, не все процессы равны. Например, процессы могут
составлять древовидную структуру [Бринч Хансен, 1970; Севсик
и др., 1972.]
В системе, предусматривающей древовидную структуру, процесс
называют отцом всех процессов, которые он образует, и процесс
называют сыном того процесса, который его образовал. Определе-
ние «предков» и «потомков» очевидно. Генеалогическое дерево про-
цессов в системе, по определению, есть ориентированный граф,
где каждый процесс представляется вершиной, а дуга выходит
из вершины А и входит в верши-
ну В тогда и только тогда, когда
А —отец В (см. рис. 2.1). Гене-
алогическое дерево описывает
упорядоченность процессов вну-
три системы в любой момент вре-
мени.
В системе с древовидной
структурой могут быть очень
строгие правила относительно
передачи ресурсов и организа-
ции управления. Например, при
образовании каждый процесс
может получить только те ресур-
сы, которые «принадлежат» его
отцу. Кроме того, отец может
иметь право контролировать дей-
ствия своих сыновей и прини-
ненормальных ситуаций. Ха-
ленное ребро, идущее из вершины А
в вершину В, означает, что процесс
А — отец процесса В.
мать меры для исправления
рактерно, что иногда только отцу разрешается проверять и из-
менять дескрипторы своих сыновей, меняя таким образом их со-
стояние.
У такой обладающей высокой степенью структурности системы
есть очевидные преимущества. Во-первых, распределение ресурсов
находится под строгим контролем. Ресурсы всякого процесса бы-
ли когда-то собственностью каждого из его предков. Если процесс
хочет освободить некоторые из своих ресурсов, он может отдать
их только своему отцу. Никогда не бывает никаких неясностей
относительно того, какой ресурс принадлежит какому процессу.
Во-вторых, вся структура в целом такова, что у одних процессов
больше власти, чем у других, т. е. в ней предусмотрен простой ме-
ханизм разделения труда. Если процесс предназначен для выпол-
нения некоторой задачи, то он может породить несколько сыновей,
каждый из которых будет выполнять часть этой задачи. Эти сы-
новья могут продолжить деление подзадач, до тех пор пока вся
задача не будет выполнена. И снова, благодаря наличию струк-
туры, всегда ясно, какому процессу принадлежит управление:
отец управляет своими сыновьями. В бесструктурной системе все
знает супервизор, т. е. у всех процессов одно и то же происхожде-
ние. Несмотря на то что централизованное управление допускает
большую свободу при разбиении задач, оно усложняет ведение учета,
поскольку супервизору приходится следить за каждым процессом
в системе. Большинство систем устроено до некоторой степени струк-
турно. Некоторые группы процессов заключают между собой ло-
кальные соглашения, которые дают одним процессам большие пра-
ва, чем другим. Некоторые системы построены «уровнями», причем
у каждого следующего уровня несколько меньше прав, чем у уровня,
образовавшего его. Такая организация приблизительно соответ-
ствует дереву, выродившемуся в длинную цепь. У каждого из этих
способов организации структуры есть свои преимущества и недо-
статки. Примеры древовидной и уровневой структур приводятся
в гл. 8 и 10.
До сих пор у наших процессов не было средств общения. После
того как их образовали и запустили, процессы работают независи-
мо, пока их не остановят или не уничтожат. Однако процессам
необходимо обмениваться информацией. Для того чтобы они могли
это делать, нужно ввести аппарат связи между процессами.
2.4. Общение между процессами
Если мы хотим использовать аппаратные и программные ресурсы
эффективно, то и те и другие подлежат разделению. Рассмотрим
задание пользователя, которое выполняется в системе как единый
программный процесс. Редко бывает, чтобы такому процессу в те-
чение всего времени его существования требовалось какое-нибудь
аппаратное устройство для единоличного пользования. Допустим,
что этот процесс пользуется каналом для работы с периферийным
устройством. Вообще канал может обслуживать запросы гораздо
скорее, чем процесс их порождает. Следовательно, есть смысл ор-
ганизовать разделение единственного канала между несколькими
процессами. Работающий в режиме разделения канал обслуживает
запросы от всех процессов и поэтому лучше используется.
Для снижения потерь из-за неэффективности столь же важно и
разделение программного оборудования. Рассмотрим обслужива-
ющую программу, например компилятор. Когда процессу нужно
оттранслировать какую-то программу, он может скопировать про-
грамму компилятора в свою область памяти и затем выполнить ее.
Если несколько процессов пользуются этим компилятором одно-
временно, то на размножение программы компилятора расходу-
ется много лишней памяти. Если держать в памяти только один
экземпляр компилятора и разрешить разделение этого экземпляра
между процессами, то можно сэкономить память. Итак, разделение
как аппаратных, так и программных ресурсов повышает эффектив-
ность системы.
Заметим, что у аппаратных и программных ресурсов есть общие
свойства. Рассмотрим систему управления файлами, которая в
каждый момент может обслуживать запросы только одного процес-
са. Даже если система управления файлами — программный ре-
сурс, ее разделение организуется так же, как и разделение многих
аппаратных ресурсов. Когда несколько процессов пытаются одно-
временно воспользоваться системой управления файлами, она мо-
жет стать столь же опасным узким местом, как и диск или централь-
ный процессор. Физические устройства называются физическими,
или естественными, ресурсами. Часть программного обеспечения,
которая ведет себя так, как будто она физический ресурс, назы-
вается логическим ресурсом. Логические ресурсы существуют только
в виде программ. Например, чтобы сделать возможным разделение
диска между несколькими процессами, в системе может быть прог-
раммно реализовано много логических дисков, которые разделяют
физический. Каждый логический диск представляет собой процесс,
который связан с дисковым каналом. Когда какой-нибудь процесс
использует логический диск, он «считает», что в его распоряжении
находится целый диск. В действительности все, что у него есть,—
это логический диск, который имитирует целое физическое устрой-
ство, посылая и получая команды от дискового канала. Процессу,
пользующемуся ресурсом, неважно, что это за ресурс — логичес-
кий, т. е. реализованный программно, или физический, т. е. реа-
лизованный аппаратно. Единственное, что процессу важно,— это
чтобы ресурс делал то, что положено. Рассматривая разделение
ресурсов, мы вообще не различаем логические и физические ресурсы,
поскольку их внешнее поведение по существу одинаково.
2.4.1. Синхронизация процессов
Несмотря на то что физические и логические ресурсы можно раз-
делять, они обычно доступны в каждый момент только одному про-
цессу. Ресурс, который допускает обслуживание только одного
пользователя за один раз, называется критическим ресурсом.
Если несколько процессов хотят пользоваться критическим ре-
сурсом в режиме разделения, им следует синхронизировать свои
действия таким образом, чтобы этот ресурс всегда находился в рас-
поряжении не более чем одного из них. Если один процесс пользу-
ется в данный момент ресурсом, то все остальные процессы, которым
нужен этот ресурс, временно получают отказ и должны ждать, пока
он не освободится. Внутри каждого процесса можно выделить
места, в которых происходит обращение к критическим ресурсам.
Эти места, называемые критическими участками, должны облагать
следующим свойством: быть взаимно исключаемыми. То есть в каждый
момент не более чём один процесс может быть занят выполнением
своего критического относительно некоторого 11 ресурса участка.
Многие физические ресурсы, как, например, лентопротяжные
или читающие с перфокарт устройства, являются критическими.
Но и разделяемые переменные, значения которых может менять
несколько процессов, тоже критические ресурсы. Например, пусть
два процесса, А и В, разделяют переменную СЧЕТЧИК. Если и А,
и В попытаются увеличить СЧЕТЧИК на 1 одновременно, то окон-
чательное значение переменной СЧЕТЧИК может оказаться не-
верным. Допустим, что события происходят в такой последователь-
ности:
1) процесс А запоминает значение переменной СЧЕТЧИК в не-
которой локальной переменной ТЕМРА;
2) процесс В запоминает^ значение переменной СЧЕТЧИК в не-
которой локальной переменной ТЕМРВ;
3) процесс А увеличивает значение ТЕМРА на 1 и записывает
его в СЧЕТЧИК;
4) процесс В увеличивает значение ТЕМРВ на 1 и записывает
его в СЧЕТЧИК-
Хотя каждый из двух процессов и увеличил переменную СЧЕТ-
ЧИК на единицу, ее окончательное значение увеличилось только па
единицу, а не на два. Чтобы избежать нежелательных явлений та-
кого рода, увеличение переменной СЧЕТЧИК следует рассматри-
вать как критический участок. Фактически всегда, когда несколько
процессов могут изменять значение разделяемой переменной,
следует во избежание ошибочных действий обращаться с этой
переменной, как с критическим ресурсом.
Рассмотрим два независимых процесса, описанных на рис. 2.2.
Каждый процесс последовательно выполняет сначала свой крити-
ческий участок, а затем какую-то другую работу. Критические участ-
ки соответствуют тем группам операций, которые обращаются к
разделяемому критическому ресурсу. Чтобы не допустить одно-
временного выполнения обоих критических участков, в системе
должен быть предусмотрен механизм, который бы синхронизи-
ровал эти два процесса. Механизм этот должен обладать двумя
свойствами. Во-первых, если один или несколько процессов хотят
обратиться к своим критическим участкам, то по меньшей мере один
из них должен в конце концов получить разрешение войти в свой
критический участок. Во-вторых, в каждый момент не более чем
одному процессу разрешается находиться в своем критическом* 2)
участке. Ниже в этой главе мы рассмотрим несколько решений
проблем синхронизации критических участков.
х) Одного и того же для всех рассматриваемых процессов.— Прим. ред.
2) Относительно фиксированного ресурса.— Прим. ред.
parbegin
ПРОЦЕСС!: do while (true);
begin
критический участок 1;
end;
оставшаяся часть процесса!;
end;
ПРОЦЕСС 2: do while (true);
begin
критический участок 2;
end
оставшаяся часть процесса 2;
end
parend
Конструкция вида:
parbegin
оператор 1;
. оператор 2;
оператор Л/
parend
означает, что операторы 1-//могут выполняться
параллельно.
Рис. 2.2. Проблема критического участка.
Процессы должны общаться не только ради синхронизации с
целью взаимного исключения, но и чтобы обмениваться информа-
цией. Например, процессы пользователя должны общаться с опера-
тором, находящимся за пультом, чтобы просить его установить маг-
нитную ленту или диск. Общение такого рода легко осуществить,
разрешив процессам передавать сообщения.
Допустим, что ПОСТАВЩИК — это процесс, который отправ-
ляет порции информации другому процессу, имя которого — ПО-
ТРЕБИТЕЛЬ. Эти порции информации можно рассматривать как
сообщения. Например, процесс пользователя, порождающий строки
для вывода, может выступать как ПОСТАВЩИК» а процесс, ко-
торый выводит эти строки на печать,— как ПОТРЕБИТЕЛЬ.
Один из методов, применяемых при реализации передачи сооб-
щений, состоит в том, что заводят пул свободных буферов, каждый
из которых может содержать одно сообщение. Между процессами
ПОСТАВЩИК и ПОТРЕБИТЕЛЬ имеется очередь заполненных
буферов, содержащих сообщения. Когда ПОСТАВЩИК хочет
послать сообщение, он добавляет в хвост этой очереди еще один
буфер. ПОТРЕБИТЕЛЬ, чтобы получить сообщение, забирает из
очереди буфер, который стоит в ее начале. Такое решение, хотя
и кажется тривиальным, требует, чтобы ПОСТАВЩИК и ПОТРЕ-
БИТЕЛЬ кооперировались во многих областях. Например, они
должны следить за количеством заполненных и свободных буферов.
ПОСТАВЩИК может передавать сообщения только до тех пор, пока
имеются свободные буферы. Аналогично ПОТРЕБИТЕЛЬ может
получать сообщения, только если очередь не пуста. Ясно, что для
учета заполненных и свободных буферов нужны разделяемые пе-
ременные. Но раз переменные используются в режиме разделения,
то потребуются и критические участки. Следовательно, изменять
значение счетчика заполненных буферов следует в режиме взаим-
ного исключения. Аналогичная проблема возникает при реализа-
ции очереди сообщений. Допустим, что очередь реализована в виде
связанного ссылками списка. Если ПОСТАВЩИК добавляет сооб-
щение в очередь как раз в тот момент, когда ПОТРЕБИТЕЛЬ
забирает из нее самое последнее сообщение, то может получиться не-
правильная ссылка. У этой ситуации есть сходство с примером, в ко-
тором два процесса увеличивали значение переменной СЧЕТЧИК.
Следовательно, работа с указателями очереди тоже представляет
собой критический участок. Короче говоря, реализация «простых»
взаимоотношений между поставщиком и потребителем требует боль-
шой тщательности.
Такие процессы, как ПОСТАВЩИК и ПОТРЕБИТЕЛЬ, об-
щающиеся на равных правах посредством какого-то внешнего ме-
ханизма, называются сопрограммами [Конвей, 1963]. Отношения
между сопрограммами не такие, как между «обращающейся» и
«вызываемой» процедурами в случае обращения к подпрограмме.
Скорее можно сказать, что они кооперируются, обращаясь друг к
другу. К сожалению, в литературе термину «сопрограмма» уже дано
много различных и противоречащих друг другу определений. Чтобы
избежать путаницы, связанной с сопрограммами, мы решили вместо
понятия сопрограммы пользоваться в этой книге понятием «коопе-
рирующиеся процессы».
В примере о поставщике и потребителе сообщения передаются
только в одном направлении. Если процессу ПОСТАВЩИК важно
знать, что его сообщение получено, то ПОТРЕБИТЕЛЬ должен
подтверждать получение каждого сообщения. Для этого требуется,
чтобы ответ передавался в противоположном направлении. Если
в системе имеется несколько пар типа «поставщик — потребитель»,
то можно организовать разделение свободных буферов, объединив
их в общий пул. Эти дополнительные усложнения в большей степени
соответствуют реальным проблемам, возникающим при проекти-
ровании системы в связи с отношениями типа «поставщик — пот-
ребитель».
В данном разделе мы рассмотрели две основные проблемы, свя-
занные с общением между процессами: проблему критических участ-
ков и проблему отношений типа «поставщик — потребитель».
В следующих двух разделах мы расскажем, как решаются эти проб-
лемы, описав в общих чертах различные приемы, которые дают про-
цессам возможность общаться эффективно, избегая при этом неже-
лательного вмешательства.
2.5. Синхронизация с помощью
элементарных приемов нижнего уровня
Большинство важнейших элементарных приемов, применяемых
для синхронизации процессов, тесно связаны с аппаратным обору-
дованием. Это блокировка памяти, операция «проверка и установка»
и семафоры.
Любого из этих приемов достаточно, чтобы реализовать и взаим-
ное исключение, и отношения типа «поставщик — потребитель»
для независимых процессов.
2.5.1. Блокировка памяти
Взаимное исключение реализуют аппаратно, сделав операции
над памятью неделимыми. То есть если каждый из двух процессов
пытается поместить какие-то значения в одну и ту же ячейку, то
спор разрешается аппаратурой: одному процессу разрешается вы-
полнить операцию засылки немедленно, а другому приходится ждать,
пока первый не кончит. Такое разрешение спора, называемое
блокировкой памяти, дает возможность реализовать взаимное
исключение двух и более процессов.
Вернемся к проблеме критического участка, изображенной на
рис. 2.2. Любое решение этой проблемы должно гарантировать, что
войти в критический участок сможет в одно и то же время не более
чем один процесс и что если один или несколько процессов хотят
войти в свой критический участок, то одному из них это обязательно
будет разрешено. Поскольку скорости обоих процессов произвольны,
указанные выше условия должны выполняться, какова бы ни была
скорость работы одного процесса относительно другого. Следующий
пример представляет собой попытку решить проблему критического
участка, не удавшуюся из-за несоблюдения последнего условия.
На рис. 2.3 каждый процесс связал со своим критическим участ-
ком переключатель, который принимает значение «истина» (true),
когда процесс находится в своем критическом участке, и «ложь»
(false) — в противном случае. Прежде чем войти в критический
участок, процесс проверяет переключатель другого процесса, чтобы
убедиться, что можно безопасно войти. Затем он «вклщчает» свой
собственный переключатель и пользуется критическим участком.
Однако безопасность этого «решения» обманчива. Пусть процесс 1
Begin boolean ПЕРЕКЛЮЧАТЕЛЬ], ПЕРЕКЛЮЧАТЕЛЬ2;
ПЕРЕКЛЮЧАТЕЛЬ] :=false;
ПЕРЕКЛЮЧАТЕЛЬ 2 :=false;
parbeg in
ПРОЦЕСС]: do while (true);
ЦИКЛ 1: do while (ПЕРЕКЛЮЧАТЕЛЬ 2);
end;
ПЕРЕКЛЮЧАТЕЛЬ! :=true;
/"критический участок iy
ПЕРЕКЛЮЧАТЕЛЬ! :=false;
/"оставшаяся часть процесса 1 у
end;
ПРОЦЕСС 2: do while (true);
ЦИКЛ 2 : do while (ПЕРЕКЛЮЧАТЕЛЬ!);
end;
ПЕРЕКЛЮЧАТЕЛЬ 2 := true;
/"критический участок 2/
ПЕРЕКЛЮЧАТЕЛЬ 2 :=false;
/"оставшаяся часть процесса 2*/
end
parend
end ~
' Рис. 2.3. Неправильное решение проблемы критического участка.
находится в цикле 1, в то время как процесс 2 находится в своем
критическом участке. Процесс 2 заканчивает выполнять свой кри-
тический участок и устанавливает в переключателе 2 значение
«ложь». Тем самым он освобождает процесс 1 от выполнения цикла 1.
Поскольку скорости произвольны, допустим, что процесс 2 работает
гораздо быстрее, чем процесс 1. Настолько быстрее, что фактически,
после того как процесс 1 обнаруживает, что в переключателе 2 сто-
ит «ложь», но прежде чем он успеет установить значение «истина»
в переключателе 1, процесс 2 пробегает свою оставшуюся часть и
перескакивает через цикл 2 (поскольку в переключателе 1 все еще
стоит значение «ложь»). Оба процесса могут «безопасно» продол-
жать работу, установив в своих соответствующих переключателях
значение «истина» и перейдя к выполнению своих критических участ-
ков. Предположив, что скорости произвольны, мы получили такую
последовательность событий, при которой оба процесса получают
возможность выполнять свои критические участки одновременно.
Таким образом, проблема критического участка в примере на рис.
2.3 не решена.
Предлагаем читателю попытаться изменить эту программу так,
чтобы она удовлетворяла ограничениям, налагаемым на решение
проблемы критического участка. Это нетривиальное упражнение.
На рис. 2.4 показано одно из возможных решений, принадлежащее
Деккеру и переписанное без операторов GOTO Р. Холтом. В этом
Begin integer d , с2, ОЧЕРЕДЬ;
с1 :=0;
с2 :=0;
ОЧЕРЕДЬ:= 1;
parbegin
ПРОЦЕСС 1: begin с1:=1;
do while (с2 = 1);
И ОЧЕРЕДЬ = 2
then begin с1:=0;
do while (0ЧЕРЕДЬ=2);
end;
d :=И
end
end;
критический участок процесса 1;
с1 :=0;
ОЧЕРЕДЬ:=2;
оставшаяся часть процесса 1
end; (
ПРОЦЕСС2: begin с2:==1; ’
do while (d = 1);
if ОЧЕРЕДЬ=1
then begin с2:=0;
do while (ОЧЕРЕДЬ»1);
end ;
c2:=1
end
end;
критический участок процесса 2;
c2 := 0;
ОЧЕРЕДЬ
оставшаяся часть процесса 2
- end
parend
end
Рис. 2.4. Алгоритм Деккера.
решении cl = 1, когда ПРОЦЕСС 1 хочет войти в свой критический
участок, с2 = 1, когда ПРОЦЕСС 2 хочет войти в свой критический
участок, а переменная ОЧЕРЕДЬ указывает, чья очередь попы-
таться войти, при условии что оба процесса хотят выполнить свои
критические участки. Чтобы оценить остроумие алгоритма Деккера,
попробуйте выполнить его вручную с различными относительными
скоростями процессов. Это решение, правильность которого до-
казана [Дейкстра, 1968а], было обобщено и для случая произволь-
ного числа процессов, конкурирующих из-за критического ресурса
[Дейкстра, 1965; Кнут, 1966].
2.5.2. Проверка и установка
Для реализации взаимного исключения процессов во многих
машинах имеются аппаратные операции, которые легче в исполь-
зовании и более эффективны, чем простая неделимая операция над
памятью. Одна из таких операций — «проверка и установка».
Л4ашинная операция «проверка и установка» значительно упро-
щает решение проблемы критического участка посредством блоки-
ровки памяти. К операции «проверка и установка» обращаются
с двумя параметрами: ЛОКАЛЬНЫЙ и ОБЩИЙ. Операция берет
значение параметра ОБЩИЙ и присваивает его переменной ЛО-
КАЛЬНЫЙ, а затем устанавливает в переменной ОБЩИЙ значение
1. Главное свойство этой операции — ее неделимость. Когда про-
цесс выполняет операцию «проверка и установка», никаких дейст-
вий не может произойти между ее началом и концом.
Переменная ОБЩИЙ разделяется между процессами, которые
подлежат синхронизации по отношению к некоторому критичес-
кому ресурсу. У каждого процесса есть своя собственная перемен-
Begin integer ОБЩИЙ;
общий :=0;
’ • parbegin
ПРОЦЕСС 1: begin integer ЛОКАЛЬНЫЙ 1;
do while (true);
ЛОКАЛЬНЫЙ 1 := 1 ;
do while (ЛОКАЛЬНЫЙ 1 = 1);
проверка и установка (ЛОКАЛЬНЫЙ 1, ОБЩИЙ)
end ;
критический участок 1;
ОБЩИЙ :=0;
оставшаяся часть процесса 1
end
end;
ПРОЦЕСС 2: begin integer ЛОКАЛЬНЫЙ 2;
do while (true) ;
ЛОКАЛЬНЫЙ 2 :=1 ;
do while (ЛОКАЛЬНЫЙ 2= 1);
проверка и установка (ЛОКАЛЬНЫЙ 2, ОБЩИЙ);
end;
критический участок 2;
ОБЩИЙ :=0;
оставшаяся часть процесса 2
end
end
parend
end
Рис. 2.5. Решение проблемы взаимного исключения с помощью операции «про-
верка и установка».
ная ЛОКАЛЬНЫЙ. В системе IBM/360 операция «проверка и уста-
новка» использует машинный признак условия в качестве локальной
переменной. Если ОБЩИЙ 1, это значит, что какой-то процесс
находится в своем критическом участке. Начальное значение пере-
менной ОБЩИЙ равно 0. На рис. 2.5 приведено решение проблемы
взаимного исключения для двух процессов, использующее опера-
цию «проверка и установка». В этом решении предполагается, что
в машине предусмотрена блокировка памяти, т. е. операция
ОБЩИЙ := 0 неделима.
Несмотря на то что и блокировка памяти, и операция «проверка
и установка» пригодны для реализации взаимного исключения,
оба эти приема очень неэффективны. Всякий раз, когда один про-
цесс выполняет свой критический участок, любой другой процесс,
который попытается войти, попадает в цикл и должен там ожидать
разрешения продолжить работу. При таком неопределенном пре-
бывании в цикле, которое называется активным ожиданием, на-
прасно расходуется процессорное время. До тех пор пока процесс,
занимающий в данный момент критический ресурс, не решит его
уступить, все другие процессы, ожидающие этого ресурса, могли
бы с тем же успехом «отправиться спать» и отдать процессоры, на
которых они работают. Когда вход в критический участок снова
будет свободен, можно будет «разбудить» один из «спящих» процес-
сов, вернуть ему процессор и разрешить доступ к критическому
ресурсу. Простым приемом синхронизации, позволяющим органи-
зовать для процессов ожидание, не прибегая к активному ожида-
нию, является «семафор».
2.5.3. Семафоры
Семафор, называемый иногда также общим семафором,— это
целая переменная, значение которой могут менять только опера-
ции Р и V [Дейкстра, 1968 а, Ы. Пусть S — семафор. Когда процесс
выполняет операцию Р (S), S уменьшается на единицу и
1) если S^O, то процесс продолжает работу;
2) если S<0, то процесс останавливается и встает в очередь
ожидания, связанную с S; он останется заблокированным
до тех пор, пока операция V (S), выполненная другим про-
цессом, не освободит его.
Когда процесс выполняет V (S), S увеличивается на единицу и
1) если S>0, то процесс продолжает работу;
2) если SCO, то один процесс удаляется из очереди ожидания
и получает разрешение продолжить работу; процесс, который
обратился к операции V (S), тоже может продолжать работу.
Кроме того, операции Р и V неделимы. В каждый момент только
один процесс может выполнять операцию Р или V над данным се-
Bejin integer СВОБОДНЫЙ;
СВОБОДНЫЙ:* 1;
parbegin
ПРОЦЕСС 1: begin
do while (true);
начало процесса 1;
Р (СВОБОДНЫЙ);
критический участок 1;
V (СВОБОДНЫЙ);
оставшаяся часть процесса 1
end
end;
; ПРОЦЕСС 2: begin
do while (true);
начало процесса 2;
P (СВОБОДНЫЙ);
критический участок 2;
V (СВОБОДНЫЙ);
оставшаяся часть процесса 2
end
end
parend
end
Рис. 2.6. Решение проблемы критического участка с использованием семафоров.
мафором. Поэтому если S=1 и два процесса одновременно попыта-
ются выполнить операцию Р (S), то только одному из них будет
позволено продолжать работу. Другой процесс будет заблокирован
и поставлен в очередь к семафору S.
Вспомним, что в разд. 2.3 мы определили стержень системы как
механизм, который реализует процессы. Стержень должен выделять
процессам и отбирать у них процессоры. Операции Р и V можно
реализовать внутри стержня, поскольку ему разрешено запускать
и останавливать процессы. При этом следует добавить условие:
в каждый момент стержень должен обслуживать только одну опе-
рацию Р или V над данным семафором; таким образом обеспечи-
вается неделимость этой операции. С добавлением такого мощного
средства, как операции Р и V, мы сможем решить проблему крити-
ческого участка без активного ожидания.
Семафор, максимальное значение которого равно единице, на-
зывается двоичным семафором. С помощью двоичного семафора про-
цессы могут организовать взаимное исключение, просто заключив
свои критические участки «в скобки», роль которых играют опера-
ции P(S) и V(S) (см. рис. 2.6). Если имеется два процесса, исполь-
зующих семафор S для синхронизации своих критических участков,
то, по определению семафора, S принимает значения 1, 0 или —1.
Если S=l, это значит, что ни один процесс не находится в своем
критическом участке. Если S=0, это значит, что один процесс
находится в своем критическом участке. Если S=—1, это значит,
что один процесс находится в своем критическом участке и один
процесс — в очереди к семафору S, где он ждет разрешения войти
в свой критический участок. Это простое решение, использующее
двоичные семафоры, применимо точно так же и в случае большого
числа процессов. В то время как алгоритм Деккера становится
весьма сложным при наличии более чем двух процессов, решение
с семафором остается тривиальным. В этом главное преимущество
подхода с применением семафора.
С помощью общих семафоров легко решается и проблема постав-
щика — потребителя (см. рис. 2.7). Переменная НАЛИЧИЕ —
это семафор, значение которого равно числу свободных буферов
в пуле. Переменная ЗАПОЛН — семафор, значение которого равно
числу заполненных буферов, которые были отосланы потребителю.
Семафор ВЗАИСК (ВЗАимное Исключение) — двоичный; он га-
рантирует, что в каждый момент только один процесс сможет рабо-
тать с буферными стрелками.
Begin integer НАЛИЧИЕ, ЗАПОЛН, ВЗАИСК;
НАЛИЧИЕ:= количество свободных буферов;
ЗАПОЛН :=0;
ВЗАИСК :=1;
parbegin
, ПОСТАВЩИК: begin
do while (true);
приготовить сообщение;
Р (НАЛИЧИЕ);
Р(ВЗАИСК);
послать сообщение;
V (ЗАПОЛН);
V(ВЗАИСК);
end
end ;
ПОТРЕБИТЕЛЬ : begin
do while (true);
P (ЗАПОЛН) ;
P (ВЗАИСК) ;
получить сообщение;
V (НАЛИЧИЕ) ;
V(ВЗАИСК);
обработать сообщение;
end
end
parend
end
Рис. 2.7. Решение проблемы поставщика—потребителя с помощью семафоров*
С помощью общих семафоров можно естественным образохм ор-
ганизовать управление ресурсами. В решении задачи о поставщике
и потребителе общие семафоры применены для учета заполненных
и свободных буферов. Их можно точно так же применить и для рас-
пределения лентопротяжных устройств, дисков, терминалов с пи-
шущими машинками. Пусть переменная ДИСК соответствует числу
имеющихся дисков. Чтобы запросить диск, процесс обращается
к операции Р (ДИСК). Освобождается диск посредством обращения
к операции V (ДИСК). При этом один и тот же диск никак не может
быть выделен двум процессам, поскольку значение переменной
ДИСК в каждый момент может уменьшать только один про-
цесс.
Семафоры можно использовать и для синхронизации. Например,
процесс 1 может попросить процесс 2 выполнить некоторую работу.
До тех пор пока процесс 2 не кончит работу, процессу 1 нечего
делать. Поэтому он обращается к операции Р (ОЖИДАНИЕ), где
ОЖИДАНИЕ — это семафор с начальным значением, равным ну-
лю. Когда процесс 2 заканчивает порученную работу, он сообщает
об этом процессу 1, выполнив для этого операцию У(ОЖИДАНИЕ).
Тогда процесс 1 «просыпается» и может продолжать работу. Такое
применение в принципе не отличается от решения проблемы крити-
ческого участка, так как процесс 2 можно рассматривать как ре-
сурс, защищенный семафором ОЖИДАНИЕ. Однако при исполь-
зовании семафоров для синхронизации и управления ресурсами
возникают трудности, связанные с организацией очереди к сема-
фору.
Если значение семафора S становится отрицательным, это зна-
чит, что в очереди, связанной с S, ожидает один или несколько
процессов. Когда выполняется очередная операция V (S), стержень
должен выбрать, какой процесс надо взять из очереди. Стержень
системы может обслуживать очередь в порядке поступления (FCFS),
т. е. брать из нее процесс, который ждет дольше всех остальных.
Можно применить и более сложный алгоритм выбора очередного
процесса, например по наивысшему приоритету. Порядок обслу-
живания очереди должен быть обусловлен целью, для которой
применяется данный семафор.
Например, рассмотрим решение проблемы критического участка
с помощью семафора. Если критический участок слишком длинный,
он часто становится узким местом для процессов, которые исполь-
зуют его совместно. Поэтому критические участки обычно делают
совсем короткими. В результате никакому процессу никогда не
приходится очень долго ждать разрешения на вход в критический
участок. Так как процессы никогда не тратят много времени на
ожидание в очереди к семафору, можно с успехом применить про-
стейший порядок обслуживания, т. е. обслуживать очередь в по-
рядке поступления. Однако для управления ресурсами и синхро-
низации часто требуется применять более сложные правила, по-
скольку времена ожидания могут оказаться существенными.
Вспомним семафор ДИСК, который мы ввели для распределения
дисков. Предположим, что все диски в данный момент распределе-
ны и что еще несколько процессов запрашивают диски, т. е. ДИСК<
<0. Когда очередной процесс, обратившись к V (ДИСК), освобож-
дает диск, может оказаться небезразличным, какой из ожидающих
процессов будет освобожден. Например, у одного из процессов,
возможно, уже есть три лентопротяжных устройства. Ясно, что
этот процесс должен получить вновь освобожденный диск раньше,
чем процесс, у которого нет дорогих ресурсов. В этом случае же-
лательно применять основанное на приоритетах правило обслужи-
вания очереди. Приоритет процесса можно определять динамически
по числу дорогих ресурсов, которыми этот процесс распоряжается.
Этот пример показывает, что при реализации очередей к семафору
в большинстве случаев нельзя удовлетвориться единым правилом
обслуживания очереди.
Обычно считается, что семафоры — подходящее средство для
удовлетворения потребностей операционной системы при реализа-
ции синхронизации и общения между процессами. И в мультипрог-
раммной системе THE (см. гл. 8), и в операционной системе «Вене-
ра» (см. гл. 10) семафоры используются как основной способ обще-
ния. Тем не менее часто семафоры очень неудобны из-за того, что
они слишком примитивны. Например, сложно реализовать с помо-
щью семафоров хитроумную схему передачи сообщений между
несколькими параллельными процессами. Применение более тон-
ких средств позволяет упростить решение таких общих задач син-
хронизации. Некоторые из этих более тонких механизмов связи
будут описаны в следующем разделе.
2.6. Элементарные приемы синхронизации
на верхнем уровне
Способы синхронизации, которые мы рассматривали до сих пор,
логически совершенны и достаточно эффективны, но их применение
сопряжено со многими опасностями. По существу элементарные,
эти способы часто приводят к сложным конструкциям, труднопос-
тижимым и весьма чувствительным к незначительным изменениям.
Небольшие отклонения в решениях проблем критического участка
и поставщика — потребителя иногда приводят к катастрофе. В этом
разделе описываются элементарные приемы синхронизации, с по-
мощью которых получаются легко понятные решения. Это дает
программисту чувство твердой уверенности в правильности прог-
раммы. Элементарные приемы верхнего уровня позволяют изящно
решить проблемы общения, хотя для их реализации обычно тре-
буются сложные и дорогие средства. Однако, поскольку при этом
уменьшается вероятность ошибки при программировании, есть ос-
нования считать такие расходы оправданными.
2.6.1. Почтовые ящики
Название «почтовый ящик» происходит от обычного приспособ-
ления для отправки почты. Если процесс Р1 хочет общаться с про-
цессом Р2, то Р1 просит систему образовать почтовый ящик, кото-
рый свяжет эти два процесса так, чтобы они могли передавать друг
другу сообщения. Для того чтобы послать процессу Р2 какое-то
сообщение, процесс Р1 просто помещает это сообщение в почтовый
ящик, откуда процесс Р2 может его в любое время взять. При при-
менении почтового ящика процесс Р2 в конце концов обязательно
получит сообщение, когда обратится за ним, если вообще обратится.
Почтовый ящик — это информационная структура, для которой
задаются правила, описывающие ее работу. Она состоит из головного
элемента, в котором находится описание данного почтового ящика,
и из нескольких гнезд, в которые помещают сообщения. Размер
каждого гнезда и количество гнезд обычно задаются при образовании
почтового ящика. Правила работы могут быть различными в зави-
симости от сложности почтового ящика. В простейшем случае
сообщения передаются только в одном направлении. Процесс Р1
может посылать сообщения до тех пор, пока имеются свободные
гнезда. Если все гнезда заполнены, то процесс Р1 может либо
ждать, либо заняться другими делами и попытаться послать сооб-
щение позже. Аналогично процесс Р2 может получать сообщения
до тех пор, пока имеются заполненные гнезда. Если сообщений нет,
то он может либо ждать сообщений, либо продолжать свою работу.
Эту простую схему почтового ящика можно усложнять в несколь-
ких направлениях и получать более хитроумные системы общения.
2.6.1.1. Двусторонняя связь
Часто бывает желательно, чтобы процесс Р1 получал от процес-
са Р2 подтверждение того, что последний получил сообщение и пред-
принял какие-то действия. Этого можно достигнуть, разрешив
передавать сообщения через почтовый ящик в обоих направлениях.
Тогда в каждом гнезде содержится либо сообщение от процесса
Р1, либо ответ от процесса Р2. Если процесс Р1 посылает сообщения
быстрее, чем процесс Р2 может ответить на них, то при такой систе-
ме возникает следующая проблема: процесс Р1 может заполнить
все гнезда, не оставив процессу Р2 свободных гнезд для ответов.
Из этого положения можно выйти, потребовав, чтобы ответы пере-
сылались в тех же самых гнездах, в которых находились вызвавшие
их сообщения. Если сообщение отослано, то соответствующее гнез-
до будет занято до тех пор, пока не будет получен ответ. Такое ог-
раничение помешает процессу Р1 засыпать процесс Р2 сообщения-
ми, на которые последний не успевает отвечать.
2.6.1.2. Многовходовые почтовые ящика
Часто бывает, что многим процессам нужно эффективно общаться
с одним процессом, который представляет собой важную обслужи-
вающую программу, как, например, система управления файлами
или служба учета. При этом возникает ситуация, которую иногда
называют «проблемой деятеля». Почтовые ящики с единственным
входом и выходом работают в этой ситуации очень неэффективно.
Каждому процессу приходится заводить отдельный почтовый ящик
для общения с обслуживающей программой. К тому же эта обслу-
живающая программа должна собирать запросы ото всех таких
почтовых ящиков. Через многовходовый почтовый ящик свои сооб-
щения могут отправлять несколько процессов. Порядок получения
сообщений можно установить какой угодно. Не приходится и го-
ворить, что многовходовые почтовые ящики труднее реализовать,
чем одновходовые. Тем не менее при решении «проблемы деятеля»
применение многовходового почтового ящика может дать выигрыш
в эффективности по сравнению с применением нескольких одно-
входовых. Аналогично можно определить многовыходовые почтовые
ящики.
2.6.1.3. Порты
Для того чтобы отправить сообщение в почтовый ящик, процесс
должен знать имя этого ящика. Иногда это требование создает
неудобства. Например, рассмотрим систему с несколькими дисками,
в которой каждому диску соответствует дисковый процесс, направ-
ляющий каналу запросы па чтение и запись. Когда какой-то про-
цесс хочет воспользоваться конкретным диском, он закрепляет
за этим диском двусторонний почтовый ящик и посылает команды
для диска через этот почтовый ящик. Дисковый процесс посылает
ответы типа «команда «писать» выполнена» или «вот запись, кото-
рую мне велели прочесть». Ясно, что дисковому процессу безраз-
лично, кто требует его услуг, поскольку запросы на чтение и за-
пись одинаковы, кто бы их ни посылал. Для того чтобы освободить
процессы от необходимости знать имена почтовых ящиков, которыми
они пользуются, можно организовать общение процессов посредст-
вом портов. Порт — это связующее звено между процессом и поч-
товым ящиком. Когда почтовый ящик соединен с определенным пор-
том, процессу, чтобы отослать сообщение, нужно указать только
имя порта. В приведенном выше примере дисковый процесс посы-
лает свои сообщения и ответы через один из своих портов, совершен-
но не интересуясь, с чьим почтовым ящиком соединен этот порт.
Имена почтовых ящиков нужно указывать только в том случае,
когда почтовый ящик физически связан с двумя портами.
Разобраться в том, как работают почтовые ящики, легче всего
на примере. Описанная ниже система почтовых ящиков была спро-
ектирована (но не реализована) для системы SUE [Атвуд и др.,
1972].
2.6.1.4. Реализация почтовых ящиков в системе SUE
Пусть процессы реализованы, как в стержне системы, описан-
ном в разд. 2.3. В проекте SUE используются двусторонние почто-
вые ящики, соединенные через порты. У процессов есть порты двух
типов: вводные и выводные. Каждый почтовый ящик связан с одним
вводным и одним выводным портом. Сообщение, посылаемое через
выводной порт, называется вопросом, а сообщение, посылаемое
через вводной порт,— ответом. Каждое гнездо почтового ящика
находится в одном из следующих четырех состояний: ожидает
вопроса, содержит вопрос, ожидает ответа, содержит ответ.
В число команд, имеющихся в системе, для управления передачей
сообщений включены команды «образовать почтовый ящик», «унич-
тожить почтовый ящик», «связать», «послать», «получить». По
принятому в проекте соглашению порт, который не связан ни с ка-
ким почтовым ящиком, считается связанным с «фиктивным почтовым
ящиком», а если почтовый ящик не связан ни с каким портом, то
он считается связанным с фиктивным портом.
Команда «образовать почтовый ящик» строит почтовый ящик
с заданными количеством и размером гнезд. Владелец почтового
ящика, т. е. образовавший его процесс, должен предоставить место
для головного элемента и гнезд. При образовании почтового ящика
его соединяют с двумя фиктивными портами.
Когда почтовый ящик уже образован, его связывают с каким-
либо портом с помощью команды «связать». Чтобы отменить связь,
ее заменяют связью с фиктивным портом или фиктивным почтовым
ящиком.
Для того чтобы послать сообщение через определенный порт,
применяется элементарная операция «послать». Эта операция про-
веряет, есть ли в почтовом ящике, соединенном с указанным вывод-
ным (или вводным) портом, гнездо в состоянии ожидания вопроса
(или ответа). Если такие гнезда найдутся, то сообщение переписы-
вается в гнездо и это гнездо получает признак состояния «содержит
вопрос» (или «содержит ответ»). Если нет гнезда в нужном состоя-
нии, то сообщение не отсылается, а процесс получает предупрежде-
ние. Это не отражается на состоянии процесса, который пытается
послать сообщение, т. е. он не блокируется.
Для того чтобы запросить сообщение, надо обратиться к коман-
де «получить», указав в качестве параметров номера выводных
(или вводных) портов. Команда «получить» последовательно пере-
бирает почтовые ящики каждого из указанных портов в поисках
такого, в котором имеется гнездо, содержащее вопрос (или ответ).
Если один из портов удовлетворяет этому условию, то сообщение
из соответствующего гнезда переписывается в область памяти,
предоставленную обратившимся к команде процессом. При обра-
щении процесс может потребовать, чтобы его заблокировали, если
для него нет сообщений, либо, наоборот, чтобы его просто извести-
ли, что сообщений нет, и дали возможность продолжать работу.
Владелец почтового ящика может в любое время уничтожить
почтовый ящик, применив элементарную операцию «уничтожить».
Если почтовый ящик к этому моменту еще связан с каким-нибудь
не фиктивным портом, то команда «уничтожить» заменяет его на
фиктивный почтовый ящик. Память, которую он занимал, возвра-
щается к предоставившему ее процессу.
2.6.1.5. Замечания
При любом из описанных выше способов организации общения
необходимо уметь однозначно указывать процесс, с которым нужно
связаться. В системе с почтовыми ящиками указывать процесс
нужно для связи с почтовым ящиком. Знание имени процесса —
это источник могущества в пределах системы. Оно дает одному про-
цессу возможность вмешиваться в связи между портами и почтовы-
ми ящиками других процессов и, быть может, даже читать их сооб-
щения. Чтобы помешать «процессам-злоумышленникам» создавать
беспорядок, система должна ввести правила, которые запрещали
бы использовать имена процессов и гнезда почтовых ящиков без
согласия владельцев. Способы проводить в жизнь такие правила
защиты будут подробно рассмотрены в гл. 7.
Почтовые ящики удобны для передачи сообщений, но использо-
вать их для синхронизации критических участков непросто. Можно
добиться синхронизации, поручив специальному процессу распо-
ряжаться доступом к критическому участку. Когда какой-то про-
цесс хочет войти в критический участок, он посылает специальному
процессу сообщение и может приступить к делу, как только полу-
чит ответ. Специальный процесс тщательно следит за тем, чтобы
в каждый момент только одному процессу было разрешено нахо-
диться в критическом участке. Решение проблемы синхронизации
с помощью такого «специального процесса» подводит нас к идее
мониторов.
2.6.2. Монитор Хоара
Монитор — это набор процедур и информационных структур,
которым процессы пользуются в режиме разделения, причем в каж-
дый момент им может пользоваться только один процесс [Хоар ц
Перро, 1972; Дейкстра, 1971]. Монитор можно представить себе
как комнату, от которой есть только один ключ. Если какой-то
процесс намеревается воспользоваться этой комнатой и ключ на-
ходится снаружи, то этот процесс может отпереть комнату, войти
и воспользоваться одной из процедур монитора. Если ключа снару-
жи нет, то процессу придется ждать, пока тот, кто пользуется ком-
натой в данный момент, не выйдет из нее и не отдаст ключ. Кроме
того, никому не разрешается оставаться в комнате навсегда.
Рассмотрим, например, ресурс, который распределяет некая
программа-планировщик. Каждый раз, когда процесс хочет полу-
чить в свое распоряжение какие-то части ресурса, он должен обра-
титься к планировщику. Процедуру-планировщик разделяют все
процессы, и каждый процесс может в любой момент захотеть обра-
титься к планировщику. Но планировщик не в состоянии обслужи-
вать более одного процесса одновременно. Значит, этот планиров-
щик представляет собой пример монитора.
Иногда монитору необходимо задержать обратившийся процесс.
Например, если процесс просит монитор выделить ресурс, который
уже кем-то используется, то монитор должен заблокировать этот
процесс до тех пор, пока нужный ресурс не освободится. Блоки-
ровка и снятие блокировки с процессов выполняются посредством
операций «ждать» и «сигнал». Когда монитор блокирует процесс
с помощью команды «ждать», он должен также указать условие,
при котором процесс может возобновить свою работу, например
«ресурс не занят». Когда условие будет выполнено, монитор вырабо-
тает «сигнал», объявляющий о выполнении этого условия. Если
какие-нибудь процессы ожидают выполнения этого условия, то
один из них пробуждается и получает разрешение продолжать ра-
боту. Вслед за этим он выполняет команду, которая непосредствен-
но следует в мониторе за командой «ждать», блокировавшей про-
цесс. Если процессов, ожидающих выполнения этого условия нет,
то «сигнал» не производит никакого действия.
В мониторе содержится одна или несколько допускающих парал-
лельное использование процедур со статическими глобальными ин-
формационными структурами. При первом обращении монитор
присваивает своим переменным из этих структур начальные значе-
ния. При каждом последующем обращении используются те зна-
чения переменных, которые остались от предыдущего обращения.
Следует подчеркнуть, что монитор — это пассивный объект, как
комната. Это не процесс. Монитор оживает только тогда, когда
какой-либо процесс решает воспользоваться его услугами. Особен-
ность программы монитора состоит в том, что в любой момент ее
может выполнять только один процесс.
Использование монитора иллюстрирует рис. 2.8, на котором
изображена реализация операций Р и V над семафором S. За-
писи вида ИМЯУСЛОВИЯ.ЖДАТЬ и ИМЯ УСЛОВИЯ.СИГИ АЛ
ДВОИЧНЫЙСЕМАФОР: monitor;
begin integer S;
condition СЕМАФОРПОЛОЖИТЕЛЬНЫЙ;
procedure P;
begin if then СЕМАФОРПОЛОЖИТЕЛЬНЫЙ.ЖДАТЬ;
s-1
end;
procedure V;
begin :=з,+1;
if J* =1 then СЕМАФОРПОЛОЖИТЕЛЬНЫЙ.СИГНАЛ
end;
<r:= 1
end
Puc. 2.8. Реализация операций P и V с помощью монитора Хоара.
относятся к операциям «ждать» и «сигнал», связанным с условием
ИМЯУСЛОВИЯ. Обращения к операциям Р и V записываются
как ДВОИЧНЫЙСЕМАФОР.Р и ДВОИЧНЫЙСЕМАФОР.У.
Условие СЕМАФОРПОЛОЖИТЕЛЬНЫЙ указывает, когда забло-
кированный процесс может безопасно продолжать работу. На рис.
2.9 два процесса взаимно исключаются из критического участка
с помощью двоичного семафора, реализованного в мониторе. Можно
было бы видоизменить этот монитор, чтобы он мог работать с не-
сколькими семафорами. Для этого надо добавить в обращение к мо-
нитору параметр, который указывает, какой семафор требуется.
Begin
parbegin
Р1 : begin
do while (true);
call ДВОИЧНЫЙСЕМАФОР.Р;
критический участок для Р1;
call ДВОИЧНЫЙСЕМАФОР.У;
оставшаяся часть Р1
end
end;
Р2 : begin
do while (true);
call ДВОИЧНЫЙСЕМАФОР.Р; ,
критический участок для Р2;
call ДВОИЧНЫЙСЕМАФОР.У;
оставшаяся часть Р2
end г
end
parend
end
Рис. 2.9. Взаимное исключение при помощи обращений к монитору.
Семантика монитора гарантирует, что если хотя бы один процесс
ожидает выполнения условия, то никакой другой обратившийся
процесс не может вмешаться между сигналом о выполнении этого
условия и продолжением ровно одного из ожидающих процессов.
Поэтому на рис. 2.8 значение S не нужно проверять заново после
операции «ждать» в процедуре Р. Сигнал означает S=l, и никакой
другой процесс не может изменить S прежде, чем один из процессов
будет освобожден. К тому же, поскольку ожидающих процессов
может быть несколько, с каждым условием связана очередь ожи-
дающих процессов. Простой порядок обслуживания очереди, сос-
тоящий в том, что освобождается процесс, который ждет дольше
всех, гарантирует, что никакой из обратившихся процессов не
будет задержан на неопределенное время.
Использование монитора в качестве основного средства синхро-
низации и связи освобождает процессы от необходимости явно
разделять между собой информацию. Напротив, доступ к разде-
ляемым переменным всегда ограничен телом монитора. Это ограни-
чение автоматически исключает критические участки. Так как в
каждый момент монитором может пользоваться только один про-
цесс, то два процесса никогда не могут получить доступ к разделяе-
мым переменным одновременно. К тому же то обстоятельство, что
разделение переменных средствами самих процессов невозможно,
позволяет системе обнаруживать попытки незаконного разделения,
случающиеся при компиляции системы.
Хотя по сравнению с семафорами мониторы не представляют
собой более мощного инструмента, у них все-таки есть некоторые
преимущества перед более примитивными синхронизирующими
средствами. Во-первых, мониторы очень гибки. В форме мониторов
можно реализовать не только семафоры, но и многие другие син-
хронизирующие операции. Например, описанный в предыдущем
разделе механизм почтовых ящиков легко запрограммировать в ви-
де монитора. Кроме того, локализация всех разделяемых перемен-
ных внутри тела монитора позволяет избавиться от малопонятных
конструкций в синхронизируемых процессах. Сложные взаимодей-
ствия процессов можно синхронизировать наглядным образом.
К тому же мониторы дают процессам возможность совместно ис-
пользовать программу, представляющую собой критический учас-
ток. Если несколько процессов совместно используют ресурс и ра-
ботают с ним совершенно одинаково, то в мониторе нужна только
одна процедура, тогда как решение с семафорами требует, чтобы
в каждом процессе имелся собственный экземпляр критического
участка. Словом, мониторы, по-видимому, обеспечивают по срав-
нению с семафорами значительное упрощение и большую нагляд-
ность при лишь незначительной потере в эффективности.
В системе SUE в качестве синхронизирующего средства реали-
зован видоизмененный вариант монитора Хоара, называемый
средством. Средство — это процесс, выполняющий обязанности
монитора. Хотя средство и несколько более гибко, чем монитор,
оно менее эффективно, поскольку ему нужны все дополнительные
информационные структуры, которые полагаются процессам. Мы
подробно рассмотрим средства в гл. 10 при описании системы SUE.
Элементарные операции связи между процессами, рассмотрен-
ные в этой главе,— это всего лишь несколько примеров, отобран-
ных нами из множества существующих средств. На выбор тех или
иных операций для конкретной системы, возможно, оказывают зна-
чительное влияние свойства аппаратуры, отражающиеся на эффек-
тивности. Но в принципе большинство синхронизирующих меха-
низмов очень похожи либо на семафоры, либо на почтовые ящики,
либо на мониторы.
2.7. Тупики
Мы изложили несколько методов синхронизации процессов,
которые позволяют процессам успешно кооперироваться. Пользуясь
элементарными операциями связи, например семафорами, процессы
могут для синхронизации своих действий блокировать друг друга
и снимать блокировку один с другого. Однако если элементарными
синхронизирующими операциями пользоваться неосторожно, то
могут возникнуть непредвиденные затруднения. Например, пусть
Р1 и Р2 — параллельные процессы (рис. 2.10). ЧТЕНИЕ и ПЕ-
ЧАТЬ — двоичные семафоры с начальными значениями, равными 1.
Если Р1 выполняет Р(ЧТЕНИЕ), в то время как Р2 выполняет
Р (ПЕЧАТЬ), то оба процесса будут заблокированы при вторых
обращениях к операции Р. Более того, они будут заблокированы
навсегда, так как ни у одного из них нет никаких шансов пройти
через второе обращение к операции Р. Такая ситуация, когда про-
цессы ждут друг друга неопределенно долго, называется тупиком.
Существует формальное определение понятия «тупиковая си-
туация», в терминах простой модели [Холт, 1972], подобной той,
которую мы описали в разд. 2.2. Пусть система представляет собой
множество состояний и множество процессов, где каждый процесс
есть функция, отображающая состояния в состояния. Процесс
заблокирован в некотором состоянии, если он не может работать,
когда система находится в этом состоянии. Процесс заперт в тупике
в некотором состоянии, если он заблокирован в этом состоянии и
во всех состояниях, в которые система может перейти в будущем.
Состояние безопасно, если никакой процесс не может отобразить
это состояние в тупиковое.
В системе со многими различными видами ресурсов тупики —
это трудная проблема. Чтобы избежать такого положения, когда
два процесса задерживают друг друга, не давая выполнить запросы
на ресурсы и не желая их освободить (как это изображено на рис.
2.10), при управлении ресурсами требуется большая осторожность.
Объявлено об этом или нет, но каждая система проводит опреде-
ленную политику по отношению к тупикам. Существует три основ-
ных направления такой политики: предотвращать, автоматически
обнаруживать, обнаруживать при участии оператора.
: Р2:
Р (ЧТЕНИЕ); Р (ПЕЧАТЬ);
Р (ПЕЧАТЬ); Р (ЧТЕНИЕ);
Рис. 2.10.
Схема предотвращения осцована на точке зрения, что систему
нельзя допускать до опасного состояния. Поэтому, когда какой-
нибудь процесс делает запрос, который может привести к тупику,
система принимает меры к тому, чтобы избежать опасного состоя-
ния: либо не удовлетворяет этот запрос, либо отбирает ресурс у
другого процесса, чтобы избежать возможного попадания в тупик.
Преимущество этого метода состоит в том, что он всегда предотвра-
щает тупиковые ситуации. Однако ресурсы часто простаивают,
поскольку запросы на имеющиеся в распоряжении системы ресурсы
отклоняются иногда с целью предотвратить попадание в опасное
состояние. К тому же и сам предотвращающий алгоритм может вне-
сти большие накладные расходы.
Метод автоматического обнаружения тупиков допускает, чтобы
система попадала в тупиковые ситуации, а когда это действительно
происходит, система обнаруживает тупик программным путем.
Затем система может отобрать ресурсы у некоторых процессов, что-
бы заставить другие процессы сдвинуться с места. В последнем
примере с чтением и печатью система допустила бы возникновение
тупиковой ситуации. Но она могла бы в этом случае отобрать пе-
чатающее устройство у процесса Р2 и отдать его процессу Р1. Про-
цесс Р2 по-прежнему оставался бы заблокированным, но оба про-
цесса больше не находились бы в тупике. Выход из тупика может
выполняться автоматически или под управлением оператора. Метод
автоматического обнаружения тупиков обычно позволяет добиться
большей загруженности ресурсов, чем политика предотвращения
тупиковых ситуаций, так как он допускает выделение ресурса про-
цессу, даже если это ведет к опасному состоянию. Если тупиковые
ситуации случаются достаточно редко, то увеличение загруженности
ресурсов с лихвой покрывает расходы на выход из тупиков.
Третий подход основан на точке зрения, что тупиковые ситуа-
ции возникают слишком редко, чтобы стоило о них беспокоиться.
Когда тупиковая ситуация все-таки возникает и оператор ее обна-
руживает, система просто запускается заново. Затраты на програм-
мное обнаружение тупика исключаются. Однако, когда тупиковая
ситуация все-таки возникает, это обходится дороже. Оператор мо-
жет некоторое время не замечать ее. И даже когда он замечает,
новый запуск системы обычно обходится довольно дорого в смысле
потери времени.
Из трех подходов к проблеме тупика задача предотвращения
привлекла, вероятно, наибольшее внимание исследователей. В сле-
дующем разделе приведен пример алгоритма предотвращения.
2.7.1. Алгоритм предотвращения тупиковых ситуаций
Рассмотрим систему, в которой процессы конкурируют из-за
лентопротяжных устройств. Если процессу предоставить все лен-
топротяжные устройства, которые ему нужны, он будет работать
в течение лишь конечного отрезка времени. Каждый процесс, до
того как он получит возможность запрашивать какие-либо ленто-
протяжные устройства, должен указать максимальное число этих
устройств, которое ему может когда-либо понадобиться одновре-
менно. Программа, распределяющая лентопротяжные устройства,
должна удовлетворять запросы на эти устройства, пока это не
может привести к тупику. То есть должна реализовываться такая
последовательность выполнения процессов, при которой каждый
процесс может окончиться. Пусть, например, система состоит из
трех процессов и десяти лентопротяжных устройств. Каждому про-
цессу соответствуют его максимальная потребность в лентопротяж-
ных устройствах, количество их, выделенное процессу в данный
момент, и количество, которое он еще имеет право потребовать.
На рис. 2.11(a) изображено типичное состояние системы. С точки
зрения вероятности тупика худший случай из возможных — это
если каждый процесс запросит все, что ему еще полагается. Если
(.а) Имя Максимальная
процесса потребность Выделено Остаток
А 4 2 2
В 6 3 3
С 8 2 6
(Ь) Имя Максимальная
процесса потребность Выделено Остаток
А 4 2 2
В 6 3 3
С 8 4 4
при таких обстоятельствах все процессы могут окончиться, то рас-
сматриваемое состояние для системы безопасно. В частности, на
рис. 2.11(a) изображено безопасное состояние. Теперь допустим,
что процесс С запрашивает еще два лентопротяжных устройства.
Если запрос процесса С будет удовлетворен и если все процессы
запросят полагающиеся им остатки (рис. 2.11(b)), то система попа-
дет в тупик. Поэтому удовлетворять запрос С опасно.
СВОБУСТР : = ОБЩУСТР;
for 7 := 1 step 1 until N do
begin СВОБУСТР : СВОБУСТР - ВЫДЕЛУСТР [/ ];
МОЖЕТНЕКОНЧИТЬ [/] :=true;
ОСТАТОК [7] :=МАКС[7] - ВЫДЕЛУСТР [/];
end ;
ПРИЗНАК :=true;
do while (ПРИЗНАК) ;
ПРИЗНАК :=false:
for 7 := 1 step 1 until A/do
begin if МОЖЕТНЕКОНЧИТЬ [7] and ОСТАТОК [7]^СВОБУСТР
then begin МОЖЕТНЕКОНЧИТЬ[7] := false;
СВОБУСТР := СВОБУСТР+ВЫДЕЛУСТР[7];
ПРИЗНАК true
end
end
end
end;
if СВОБУСТР = ОБЩУСТР then состояние системы безопасное
else состояние системы небезопасное
Рис. 2.12. «Алгоритм банкира».
Вообще выяснять, ведет ли удовлетворение некоторого запроса
к опасному состоянию, можно с помощью специальных алгоритмов.
Одна такая процедура, называемая «алгоритмом банкира», работает
по только что описанному принципу (Дейкстра, 1968 а). Новое сос-
тояние безопасно тогда и только тогда, когда каждый процесс все
же может окончиться. Именно это последнее условие и проверяется
в «алгоритме банкира».
«Алгоритм банкира» (рис. 2.12) напоминает процедуру принятия
решения, может ли банк безопасно выпустить заем. Каждому про-
цессу поставлено в соответствие целое число i (l^t^M). Процессу i
соответствуют его максимальная потребность в устройствах
МАКС [7], количество устройств, выделенных ему в данный момент
(ВЫДЕЛУСТР [/]), полагающийся ему остаток (ОСТАТОК Id) и
признак (МОЖЕТНЕКОНЧИТЬ [/]). Система заводит глобальную
переменную ОБЩ, обозначающую общее число имеющихся в систе-
ме устройств. В начале работы неизвестно, может ли какой-либо
процесс окончиться (МОЖЕТНЕКОНЧИТЬ [f]=true для всех I).
Каждый раз, когда какой-то ОСТАТОК может быть выделен из
числа остающихся незанятыми устройств, предполагается, что со-
ответствующий процесс работает, пока не окончится, а затем его
устройства освобождаются. Если в конце концов все устройства
освободятся, значит, все процессы могут окончиться и система
находится в безопасном состоянии. Если состояние системы не
безопасное, то она не удовлетворяет рассматриваемый запрос.
2.7.2. Заключительные замечания
Хотя «алгоритм банкира» прост, его реализация может обой-
тись довольно дорого, так как обращаться к нему нужно каждый
раз, когда какой-то процесс запрашивает очередное устройство.
Более простой способ состоит в том, что каждый процесс запраши-
вает сразу максимальное нужное количество устройств. Для того
чтобы увеличить число имеющихся в его распоряжении устройств,
процесс должен сначала отдать то, что у него в данный момент
имеется. Хотя при такой системе распределения некоторые процес-
сы вынуждены запрашивать ресурсы задолго до того, как они дейст-
вительно понадобятся, реализовать ее значительно проще, чем
«алгоритм банкира», поскольку система всегда находится в безо-
пасном состоянии. Этот способ распределения ресурсов часто при-
меняется в операционных системах.
Тупики — это важная и интересная проблема. Она принадле-
жит к числу наиболее легко формализуемых задач, связанных с опе-
рационными системами, вследствие чего в этой области были про-
ведены обширные исследования (например, Коффман и др., 1971;
Хаберман, 1969; Холт, 1972; Хебалкар, 1970). В частности, мы
включили в приложение II модель Холта, построенную средствами
теории графов. Однако, несмотря на то что существует развитая
теория проблемы тупиков, все еще распространены и простые схе-
мы. Накладные расходы, порождаемые предотвращением тупиковых
ситуаций в производственных системах, как правило, слишком
велики по сравнению со стоимостью случающихся время от времени
отказов системы.
Задания
2.1. В чем разница между явным параллелизмом, характерным,
например, для организации машины ILLIAC IV, и неявным парал-
лелизмом, характерным, например, для организации машины IBM
370/195? При какой организации потенциальные производственные
возможности машины выше? Для какой машины легче программи-
ровать? Почему?
2.2. Рассмотрим программу на рис. 2.4, реализующую алгоритм
Деккера. Определите внутренние состояния программы и переходы
от состояния к состоянию, которые описывают ход работы алго-
ритма.
2.3. Рассмотрим набор из восьми частично упорядоченных заданий
{Л, В, С, D, Е\ F, G, Н}. Задание А должно предшествовать зада-
ниям С, В и Е. Задания Е и D должны предшествовать заданию F.
Задания С и В должны предшествовать заданию D. Задание F
должно предшествовать заданиям G и Н.
(а) Изобразите выполнение этой последовательности заданий
в виде программы с помощью элементарных операций «parbegin»
и «parend», используя везде, где возможно, параллелизм заданий.
(Ь) Теперь допустим, что добавлено дополнительное ограничение:
задание Е должно предшествовать заданию С. Можете ли вы по-
прежнему найти «максимально использующее параллельность» ре-
шение с помощью операций «parbegin» и «parend»?
(с) Если бы было разрешено пользоваться семафорами, как бы
изменились ваши ответы на вопросы (а) и (Ь)?
2.4. Рассмотрим определение процесса, которое было дано в разд.
2.2. Определите набор переменных и последовательность действий
для вычисления произведения двух матриц размерности пХп. Пол-
ностью ли вы используете допустимый параллелизм?
2.5. Используя защиту памяти, организуйте взаимное исключение
между п процессами, у каждого из которых есть один критический
участок.
2.6. Опишите в общих чертах, как можно реализовать взаимоотно-
шения поставщика и потребителя, используя защиту памяти. Для
организации взаимного исключения воспользуйтесь алгоритмом
Деккера как макрокомандой.
2.7. Задача о спящем парикмахере [Дейкстра, 1968 а]. Парикма-
херская состоит из комнаты ожидания W и комнаты В, в которой
стоят парикмахерские кресла. Через раздвижные двери D можно
попасть из комнаты В в комнату IF, а из комнаты W на улицу.
Если парикмахер заходит в комнату W и никого там не обнаружи-
вает, то он идет спать. Если клиент входит в' парикмахерскую и
находит парикмахера спящим, то он должен его разбудить. В ком-
нате ожидания имеется конечное число стульев п. Запрограмми-
руйте парикмахера и клиентов как процессы. Для синхронизации
их работы воспользуйтесь аппаратом пересылки сообщений. Что,
если бы было два парикмахера? Опишите работу парикмахерской
с помощью сетей Петри, как показано в разд. II.2.
2.8. Пусть дан обеденный стол с пятью стульями и пятью прибо-
рами. Около каждого прибора имеется вилка. Чтобы съесть свою
порцию спагетти, гостю необходимы две вилки, находящиеся по
соседству с его тарелкой. Пусть за столом сидят пятеро гостей,
которые попеременно то едят спагетти, то говорят о политике (для
разговоров о политике вилок не требуется). Запрограммируйте
гостей как набор процессов, используя семафоры для передачи
сообщений. Позаботьтесь о том, чтобы возможность тупика между
гостями была исключена [Дейкстра, 1971].
2.9. Рассмотрим очень простую операционную систему, состоящую
из главного процесса /И, работающего с центральным процессо-
ром, читающего процесса /?, который работает с читающим каналом,
и печатающего процесса Р, который работает с печатающим кана-
лом. Запрограммируйте эти три процесса так, чтобы процесс R
читал данные и передавал их процессу М, который обрабатывал бы
эти данные и передавал процессу Р для выдачи на печать. Запрограм-
мируйте процессы Л1, R и Р для случаев, когда имеются
(а) два буферных пула, содержащие по К буферов;
(Ь) один буферный пул, содержащий /С буферов.
2.10. Иногда в системе возникает необходимость передать от про-
цесса к процессу довольно длинное сообщение, например какой-то
файл. Обычный аппарат почтовых ящиков здесь, очевидно, был бы
неэффективен, поскольку он предусматривает, что сообщение пол-
ностью переписывается из одного места оперативной памяти в дру-
гое. Укажите способ передачи длинных сообщений при условии,
что существует возможность посылать короткие сообщения.
2.11. Рассмотрим операционную систему, в которой процессы об-
щаются посредством передачи сообщений. Послав сообщение, про-
цесс А ожидает ответа. Но иногда в процессе, который должен
послать ответ, происходит ошибка и ответ вообще не отсылается.
Если процесс А отправляется спать, пока не придет команда «ПО-
ЛУЧИТЬ СООБЩЕНИЕ», то он больше никогда не проснется.
Один из примеров, позволяющих обойти эту трудность, состоит в
том, что процесс А устанавливает «будильник», который должен
разбудить его, если в течение заранее указанного времени не при-
дет ответ. Постройте специальный процесс, который бы, пользуясь
аппаратным реле времени, посылал сигналы тем процессам, кото-
рые его об этом попросят.
2.12. Процессы и аппарат общения между ними могут порождать
значительные издержки в операционной системе. Постройте деск-
риптор процесса и средство общения между процессами, которые
были бы очень просты и эффективны. Там, где потребуется, можете
пожертвовать общностью и гибкостью системы.
2.13. Рассмотрим набор процессов, в котором каждому процессу
однозначно соответствует целое число. У каждого процесса есть
особый участок, в который можно войти только при условии, что
сумма всех целых чисел, соответствующих процессам, которые ра-
ботают в данный момент в своих особых участках, делится на три.
Опишите в общих чертах реализацию этих особых участков с по-
мощью семафоров. Дайте краткое описание другой реализации,
использующей монитор Хоара. Сравните эти два решения. Возмож-
но ли, чтобы при предложенных вами реализациях.какой-то про-
цесс был навсегда отрезан от своего особого участка?
2.14. Аппарату пересылки сообщений необходима оперативная па-
мять для сообщений. Один из подходов состоит в том, что отправи-
тель выделяет место для сообщения из своего рабочего пространст-
ва. При другом подходе система содержит для этой цели пул буфе-
ров. Рассмотрите относительные достоинства этих двух подходов.
2.15. Пользуясь монитором, реализуйте взаимоотношения между
поставщиком и потребителем.
2.16. Рассмотрим сеть вычислительных машин. Опишите в общих
чертах аппарат, который можно применить для организации обще-
ния между процессами, работающими в различных узлах сети.
2.17. Сделайте обзор типов тупиков и алгоритмов, предотвраща-
ющих и выявляющих тупики.
2.18. Сделайте обзор абстрактных моделей параллельных вычисле-
ний, как в примере из разд. II.2. Кратко изложите различные тео-
ретические результаты, которые получаются при таких моделях.
2.19. Напишите реферат о сетях Петри и связанных с ними теоре-
тических результатах.
2.20. Пусть имеется два класса процессов (будем называть их «чи-
тающие» и ’«записывающие» процессы), которые могут обращаться
к критическому ресурсу, например к файлу. Записывающие про-
цессы должны иметь исключительное право доступа к ресурсу.
Сколько угодно читающих процессов могут обращаться к ресурсу
при условии, что с ним в это время не работает ни один записываю-
щий процесс. Будем считать, что читающий процесс получает отказ
в доступе только в том случае, если в этот момент к ресурсу обра-
щается некоторый записывающий процесс. Запрограммируйте чи-
тающие и записывающие процессы как конкурирующие, применяя
для синхронизации семафоры [Ку рту а и др., 19711.
Глава 3
РАСПРЕДЕЛЕНИЕ ВРЕМЕНИ
ПРОЦЕССОРА
3.1. Введение
Время процессора всегда было важнейшим из ресурсов системы,
подлежащих распределению. Несмотря на возрастающее значение
памяти и устройств ввода-вывода, распределение времени процес-
сорадо сих пор играет главную роль. Очевидно, что процесс не может
продвинуться в своей работе без процессора. Для современных быст-
родействующих вычислительных машин каждая секунда — это мил-
лионы операций. Даже небольшое количество потерянного процес-
сорного времени означает огромную потерю производительности
машины. Вследствие этого большинство разработчиков систем уде-
ляет значительное внимание эффективному использованию процес-
сора.
В этой главе задание мы определим как совокупность вычисле-
ний, состоящую из одного или нескольких модулей. Каждый мо-
дуль содержит программу на языке машины и (или) какие-то дан-
ные. Задача системы — эффективно планировать порядок, в котором
должны выполняться задания пользователей.
Глава начинается с очерка развития схем распределения про-
цессорного времени в порядке возрастания их сложности [Розин,
1969]. Затем мы рассмотрим ту же задачу в более современной поста-
новке, например в условиях мультипрограммирования. В заключе-
ние мы опишем разнообразные типы планирующих алгоритмов и их
реализации.
3.1.1. Машина „на одну персону"
Первое время вычислительная машина предоставлялась на не-
которое время каждый раз только одному пользователю. На не-
больших машинах и сейчас часто работают подобным образом.
С распространением мини-машин такое положение стало особенно
типичным. Пользователь устанавливает свои ленты и пакеты дис-
ков, затем садится за пульт и пропускает свою программу. Работать
на такой машине не очень трудно, поскольку система обычно проста
и нетороплива, так что есть время подумать. В распоряжение прог-
раммы пользователя предоставлены и кое-какие системные средства,
например стандартные программы ввода-вывода и обслуживающие
программы. Однако система не защищает пользователя от его соб-
ственных ошибок. Программа должна сама синхронизировать свою
работу со всеми операциями ввода-вывода. Она должна проверять
метки на лентах и дисках, посылать сообщения на пульт и сигна-
лизировать пользователю о ненормальных программных ситуа-
циях, таких, как переполнение. Операционная система либо отсут-
ствует, либо мало чем помогает в таких делах. Фактически пользо-
ватель предоставлен самому себе.
Пропускная способность машины при единичном пользовании
часто очень мала. Много времени теряется, пока программист
устанавливает ленты, вводит карты и т. д. Кроме того, машина и
сама зря тратит часть времени, так как процессор обычно простаи-
вает, пока выполняются команды ввода-вывода. Для более быстрых
и мощных машин такой способ работы становится чересчур расто-
чительным. Поэтому для больших систем нужны более эффектив-
ные методы работы.
3.1.2. Пакетный режим
(одновременный ввод заданий из файла)
По мере того как возрастает стоимость вычислительного обору-
дования, длительные простои становятся все более недопустимыми.
Чтобы сократить время простоя, применяют системы пакетной об-
работки. Такая система накапливает на входной ленте большое
число заданий. Задания считываются малой машиной-сателлитом,
которая и подготавливает входную ленту. Затем главный процессор
одну за другой выполняет программы, поступающие с входной лен-
ты, и записывает результаты на выводную ленту. Тем временем
сателлит может создавать следующую входную ленту и распечаты-
вать предыдущую выводную. Типичный пример системы пакетной
обработки — система IBSYS для машины IBM 7090 с IBM 1401
в качестве сателлита.
Задания с входной ленты обрабатываются в порядке поступле-
ния. Поэтому если машина затрачивает один час на обработку вход-
ной ленты, то среднее время прохождения г) для любого задания
составит, вероятно, около двух-трех часов, в зависимости от скоро-
сти сателлита. При таком способе обработки короткие задания
никак не выделяются. У пятнадцатиминутного задания то же среднее
время прохождения, что и у пятнадцатисекундного. Таким образом,
ничто, кроме стоимости машинного времени, не побуждает пользо-
вателя уменьшать продолжительность выполнения программы.
Пакетный режим — это несложный прием. Он дает хорошую
пропускную способность. Это определенное улучшение по сравне-
нию с машиной для индивидуального пользования. Однако пакет-
ная обработка может затруднить отладку, так как она исключает
прямое взаимодействие между программистом и его программой.
х) То есть время от ввода в машину до получения результата.— Прим, перев.
Поэтому пакетный режим лучше всего проявляет себя в производ-
ственных системах, где большие задания выполняются периодиче-
ски по определенному расписанию.
3.1.3. Система с прямой связью
В системе с прямой связью две машины (или больше) обменива-
ются информацией из памяти в память. Более медленная машина,
называемая главной, занимается планированием заданий для более
быстрой машины, которая называется подчиненной. Главная машина
считывает задания с устройства чтения перфокарт и, поставив их
в очередь, помещает на диск. Когда подчиненная машина заканчи-
вает выполнение задания, она посылает главной машине запрос о
дальнейшей работе. Главная машина управляет планированием,
учетом и вводом-выводом. В обязанности подчиненной машины вхо-
дит только чисто вычислительная работа для заданий пользовате-
лей. Она освобождена от решения организационных вопросов и
может посвятить все свое время производительному труду.
Планирование заданий может быть очень хитроумным и сильно
зависит от назначения системы. Анализ алгоритмов планирования
мы отложим до разд. 3.3.
3.2. Мультипрограммирование
В мультипрограммных системах по частям выполняются нес-
колько заданий сразу. Обычно задания находятся в основной памяти,
и центральный процессор тратит какую-то долю своего времени на
выполнение каждого из них. Главной причиной возникновения
мультипрограммирования было стремление компенсировать разли-
чие в скоростях между вычислениями и вводом-выводом. Операции
ввода-вывода выполняются гораздо медленнее, чем процессорные.
Когда задание выдает каналу команду читать, оно должно ждать,
пока канал не окончит чтение. В мультипрограммной системе,
вместо того чтобы позволить процессору простаивать во время ввода-
вывода, можно переключить его на выполнение другого задания.
Задание, которое в данный момент выполняет ввод-вывод, снова
получит в свое распоряжение процессор через некоторое время
после завершения ввода-вывода. Так как в основной памяти одно-
временно находится несколько заданий, то процессор будет простаи-
вать только в том случае, если все они ожидают завершения работы
канала.
Будем называть задание активным, если оно находится в опера-
тивной памяти и может выполняться. Количество активных зада-
ний может изменяться в определенных пределах или произвольно.
Желательно, чтобы активных заданий было как можно больше,
тогда процессор будет простаивать редко. Однако для того, чтобы
задание было активным, оно должно находиться в оперативной
памяти. Это приводит к серьезной конкуренции между заданиями
из-за места в памяти. Поэтому возможность эффективно заполнять
оперативную память — существенное требование, предъявляемое
к стратегиям распределения памяти.
Совокупность активных заданий в системе называется рабочей
смесью. Отбор заданий в рабочую смесь — это решающий момент
в мультипрограммной систехме. Обычно желательно, чтобы среди
активных заданий было хотя бы одно «вычислительное», т. е. такое,
которое большую часть своего времени занято вычислениями и вы-
полняет очень мало операций ввода-вывода. Даже если все осталь-
ные задания заняты вводом-выводом, можно рассчитывать на то,
что вычислительное задание обеспечит процессор работой. Посколь-
ку желательно держать в оперативной памяти много заданий одно-
временно, весьма полезны бывают задания, требующие мало места
в памяти. Задание можно сделать «маленьким» искусственно, разме-
щая в оперативной памяти всегда только часть программы и данных
задания. Остальная часть задания находится на барабане или на
диске. Когда требуются находящиеся во вспомогательной памяти
команды или данные, система временно приостанавливает задание
(т. е. делает его неактивным) и передает дополнительную информа-
цию с периферийного устройства в оперативную память. Такой
способ управления памятью позволяет поддерживать в активном
состоянии больше заданий, так как в памяти всегда находится
только часть каждого задания.
Время простоя процессора следует сводить к минимуму, однако
у системы есть и другие задачи. Периферийные устройства тоже
следует использовать как можно более эффективно. Система должна
отдавать предпочтение активным заданиям, которые заставляют
работать лентопротяжные и печатающие устройства, диски и уст-
ройства для чтения карт. Система явно не уравновешена, если все
активные задания используют диски, но ни одно из них не исполь-
зует ленты. Ясно, что очень полезно знать заранее, какие ресурсы
необходимы заданию. Однако задача уравновешивания системы,
т. е. обеспечения занятости всех ресурсов, чрезвычайно трудна, и
оптимальные решения известны только для очень простых случаев.
Поэтому методы отбора заданий в рабочую смесь основаны больше
на интуиции и опыте, чем на каких-либо строгих математических
исследованиях задачи уравновешивания системы.
3.2.1. Разделение времени
Система с разделением времени взаимодействует со многими поль-
зователями, постоянно уделяя внимание каждому из них в отдель-
ности. Обычно такой режим реализуется посредством мультипрог-
раммирования. Системы, которые постоянно обрабатывают запросы
от многих пользователей, но не хранят в оперативной памяти по
нескольку заданий одновременно, реализуются очень редко. Быст-
рота ответов системы позволяет значительно улучшить условия об-
щения человека с машиной. Разделение времени совмещает тесный
контакт с человеком, характерный для машины «на одну персону»,
с эффективностью пакетной обработки. Подобный режим работы
с пользователями иногда называют работой в реальном масштабе
времени (в задачах управления) или оперативным (в производст-
венно-экономических приложениях).
3.2.2. Квантование времени
В условиях мультипрограммирования необходимо распределять
время процессора между активными заданиями. Чтобы осуществить
разделение, время процессора разбивается на интервалы и каждо-
му заданию время от времени выделяется один интервал. Такой
интервал называется долей времени или квантом. Например, если
в памяти находится пять заданий, то каждое может получать по
кванту, равному одной секунде, каждые пять секунд. Но кванты
не обязательно равны для всех заданий. На частоту получения
заданием квантов времени и их величину обычно влияют различ-
ные факторы, такие, как приоритет задания и требования процес-
сора.
Квантование времени особенно важно в системах с разделением
времени, где каждый пользователь ожидает постоянного внимания.
Короткие кванты создают у каждого пользователя иллюзию, что
машина выполняет только его задание. Система может предоставлять
каждому пользователю кванты по 0,1 секунды каждую секунду.
Пользователь просто видит, что его задание выполняет машина,
которая, как ему кажется, работает в десять раз медленнее, чем
реальная.
Существует множество алгоритмов распределения квантов вре-
мени между несколькими заданиями. Ниже в этой главе мы рас-
смотрим некоторые распространенные методы планирования в муль-
типрограммных системах.
3.3. Методы планирования
в мультипрограммных системах
В мультипрограммных системах несколько активных заданий
конкурируют из-за процессорного времени. Допустим, что каждое
задание пользователя выполняется в системе, как один процесс.
Кроме процессов пользователей, существуют еще системные про-
цессы, которые также участвуют в использовании процессора. Все
активные процессы, ожидающие, когда им будет выделен процессор,
стоят в очереди готовых процессов. Процессы, которые заблокирова-
ны (например, ожидают, когда завершится ввод-вывод или откроет-
ся семафор), стоят в отдельных очередях заблокированных процес-
сов. На рис. 3.1 схематически изображены эти очереди: R — сово-
купность, состоящая из одной или нескольких очередей готовых
процессов; Р — процессор. Соответственно очередям R и В процесс
Рис. 3.1. Схема планирования распределения процессора. (R — очередь (или оче-
реди) готовых процессов; В — очередь (или очереди) заблокированных процес-
сов; Р — процессор.)
может находиться в следующих состояниях: готовый, заблокирован-
ный или выполняемый. Пусть некоторому процессу из очередей
готовых процессов предоставляется квант процессорного времени.
Процесс выполняется до тех пор, пока не произойдет одно из сле-
дующих событий: истечет его квант времени, или процесс будет за-
блокирован (например, из-за операции ввода-вывода), или он за-
вершится, или он будет вытеснен другим процессом, имеющим
преимущественное право на процессорное время. Прекратив работу
по одной из четырех указанных причин, процесс либо возвращается
в очередь готовых процессов, либо отправляется в очередь заблоки-
рованных процессов, либо выходит из системы. Процесс переводится
из очереди заблокированных процессов в очередь готовых процес-
сов, когда с него снимается блокировка. Алгоритм планирования
для такой системы очередей включает в себя способ выбора готового
процесса из совокупности R и способ вычисления величины кванта
для него.
Каждому процессу из очереди готовых процессов поставлено в
соответствие целое число, называемое приоритетом и обозначаю-
щее важность процесса. Вычисление приоритета основано как на
статических, так и на динамических характеристиках процесса.
Статические характеристики включают количество занимаемой па-
мяти, ожидаемое время выполнения и ожидаемый объем ввода-вы-
вода. Если процесс представляет собой задание пользователя, то
одной из статических компонент может быть также «коэффициент
важности», назначаемый пользователем. Обычно он задается в виде
приоритета на колоде карт, содержащей задание, и называется
внешним приоритетом. На приоритет влияет также динамическое
поведение процесса в системе. Ресурсы, находящиеся в данный
момент в распоряжении процесса, общее время ожидания, количе-
ство процессорного времени, полученного последний раз, объем
последних операций ввода-вывода и общее время нахождения в сис-
теме могут учитываться при вычислении приоритета. Поскольку
эти характеристики меняются во времени, приоритет может вычис-
ляться заново много раз на протяжении жизни процесса.
В большинстве систем внешний приоритет играет второстепен-
ную роль в вычислении приоритета для очереди готовых процессов.
Внешний приоритет полезен главным образом при первоначальном
вводе задания в активное состояние и для ускорения распечатки
результатов, когда оно выполнено. Так как для большинства зада-
ний время выполнения очень мало по сравнению со временем, кото-
рое тратится на ожидание загрузки в оперативную память и на ожи-
дание распечатки, то увеличение веса внешнего приоритета в прио-
ритете готовых процессов оказало бы минимальное влияние на
время прохождения, но могло бы иметь катастрофические последст-
вия для уравновешенности рабочей смеси.
Многие системные процессы выполняются так, как если бы они
были заданиями пользователей. В эту категорию попадают учет,
управление стандартными программами и их эксплуатация. Но для
некоторых системных процессов нужны особые привилегии. На-
пример, не следует задерживать процесс, управляющий внешним
устройством, если он готов использовать процессор. Пока он не
получит процессор, связанный с ним канал, возможно, будет про-
стаивать, ожидая команды запуска. Итак, чтобы избежать простоя
периферийных устройств, некоторым процессам дают привилегии,
позволяющие им легче, чем процессам пользователей, получать
процессорное время. Хотя при обсуждении конкретных алгоритмов
планирования мы не будем особо отмечать эти процессы, следует
четко представлять себе, что фактически все правила планирования
должны учитывать существование привилегированных процессов.
Например, при алгоритме планирования, отдающем предпочтение
процессу с наивысшим приоритетом, привилегированным процессам
обычно присваивают бесконечный приоритет.
При планировании очередей готовых процессов системе прихо-
дится учитывать многочисленные показатели производительности,
такие, как хорошая загруженность ресурсов, малое время простоя,
высокая пропускная способность и разумное время ожидания для
заданий пользователей. Имеется еще дополнительное ограничение:
ни одно задание в системе не должно ждать вечно. Иногда эти цели
противоречат друг другу. Например, уменьшение среднего времени
ответа может привести к тому, что некоторым большим заданиям
придется долго ждать, прежде чем они начнут выполняться. Один
из подходов к выводу правила планирования формулируется в тер-
минах функции потерь. Функция потерь выражает значение завер-
шения задания как функцию времени его задержки. С ней связаны
такие параметры, как время ожидания, общее время пребывания
в системе и крайний срок выполнения. Система стремится планиро-
вать процессы так, чтобы свести к минимуму средние потери или
ограничить максимальные потери по всем заданиям. Однако мини-
мизация потерь может не согласовываться с хорошей загруженно-
стью системы. Например, минимизация среднего времени ожидания
может отсрочить выполнение длинных заданий. Допустим, что ка-
кое-то длинное задание использует не подлежащий разделению
ресурс. Тогда можно повысить эффективность использования этого
ресурса, если быстрее выполнить данное задание. Решение — вы-
полнять или не выполнять это длинное задание — зависит от того,
какой показатель производительности системы считается более важ-
ным. Вообще говоря, правила планирования в реальных системах
отражают стремление получить приемлемые эксплуатационные ха-
рактеристики сразу в нескольких направлениях. Хотя ни один
показатель в отдельности не оптимизируется, достигается общая
хорошая производительность системы.
В этом разделе мы рассмотрим три класса алгоритмов планиро-
вания: по наивысшему приоритету, круговорот и планирование с
обратной связью [Коффман и Клейнрок, 1968]. Обслуживание в
порядке поступления (FCFS х)) иногда упоминается для сравнения.
Эги три основных правила охватывают большую часть проблем,
связанных с планированием процессов, и обобщаются для многих
проблем распределения других ресурсов.
3.3.1. Планирование по наивысшему приоритету
Один из простых методов планирования очереди готовых про-
цессов состоит в том, что процессор предоставляется тому про-
цессу, который имеет наивысший приоритет (правило HPF* 2)). Если
вытеснение не допускается, то процесс с наивысшим приоритетом вы-
полняется до тех пор, пока не кончится или не заблокирует сам себя.
Если в очередь поступает процесс с более высоким приоритетом,
чем у текущего процесса, то он должен ждать, пока текущий процесс
не освободит процессор. Если вытеснение разрешено, то при появле-
х) По первым буквам «first-come-first-served», что означает «первым пришел —
первым обслужен».— Прим, перев.
2) По первым буквам «highest priority first», что означает «наивысший приори-
тет — первым».— Прим, перев.
нии процесса с более высоким приоритетом текущий процесс преры-
вается и управление переходит к вновь прибывшему процессу. Вы-
тесненный процесс возвращается в очередь готовых процессов.
В правиле наивысшего приоритета компоненты приоритета, приме-
нение вытеснений и организация очереди являются свободными
параметрами реализации.
Каждый раз, когда процессор освобождается, из очереди го-
товых процессов должно быть извлечено задание с наибольшим при-
оритетом. Если очередь упорядочена, то извлечь первый элемент
просто. Но чтобы поставить процесс в такую очередь, требуется мно-
го времени: для каждой операции вставления нужно перебрать
в среднем половину очереди, если считать, что элементы связаны
в двусторонний список, т. е. с указателями из начала в конец и из
конца в начало очереди. Если очередь не упорядочена, то ее надо
просматривать каждый раз, когда нужен новый процесс, зато опе-
рация вставления тривиальна. Возможны также компромиссные
стратегии. Например, очередь можно упорядочивать через каждые Т
единиц времени. Когда поступает новый процесс, он ставится в на-
чало очереди. Но при этом сохраняется ссылка Р, которая указы-
вает на начало рассортированной части списка. Поиск процесса
с наивысшим приоритетом начинается со ссылки Р и продолжается
в направлении начала очереди. Количество элементов, которые при-
ходится перебирать, меньше, чем в случае неупорядоченной очере-
ди, а время сортировки здесь сокращено по сравнению со случаем
строго упорядоченной очереди. Правда, ради простоты в системах
обычно применяют упорядоченную очередь готовых процессов.
Если пользоваться стратегией HPF, то прежде всего нужно ре-
шить, на каких характеристиках будет основан приоритет. Одна из
наиболее часто упоминаемых в литературе стратегий HPF выбирает
каждый раз самое короткое задание (SJF х)), т. е. приоритет обратно
пропорционален времени обработки. Так как точное время выполне-
ния процесса редко известно заранее, для определения приоритета
обычно применяется ожидаемое время. Очевидно, что процессу выгод-
но иметь небольшое ожидаемое время выполнения. Пользователи
могут сознательно указывать неверное ожидаемое время с целью по-
высить свой приоритет. С этим можно бороться, наказывая пользо-
вателей, которые занижают ожидаемое время выполнения. Напри-
мер, для процессов, выходящих за пределы своей оценки, может
быть увеличена цена машинного времени.
Правило SJF можно реализовать с вытеснениями или без них.
Если вытеснение запрещено, то процессы всегда работают до тех
пор, пока не закончатся или не заблокируются. В случае когда раз-
решены вытеснения, если поступает процесс с меньшим ожидаемым
г) По первым буквам «shortest job first», что означает «кратчайшее задание —
первым».— Прим, перев.
3.3. Методы планирования в мультипрограммных системах 81
временем, чем у текущего процесса, то последний вытесняется и его
место занимает новый процесс. Для коротких процессов стратегия
с вытеснениями лучше, чем без вытеснений. Если вытеснения раз-
решены, то длинным процессам становится труднее удерживать
процессор в своем распоряжении.
Хотя вытеснение улучшает обслуживание коротких процессов,
с ним сопряжены определенные издержки. Вытеснение требует како-
го-то времени и тем самым задерживает всю очередь готовых про-
цессов. Поэтому если выполняемый процесс близок к завершению
своей работы, то, видимо, не стоит вытеснять его.
Для типичных распределений величины времени выполнения
характерно преобладание коротких процессов. В таких условиях
правило SJF работает вполне успешно, так как оно весьма благо-
приятствует коротким заданиям. Правда, длинные процессы об-
служиваются плохо. Если система сильно загружена, то с длин-
ными процессами дело обстоит особенно плохо, и это положение
еще усугубляется, если разрешено вытеснение. Впрочем, если сис-
тема близка к пределу своих возможностей, то любое правило плани-
рования работает не вполне хорошо.
Поскольку предварительная информация о времени выполне-
ния обычно очень неточна, во многих стратегиях планирования
предпринимаются попытки основывать выбор на информации о про-
цессе, полученной за время его пребывания в системе. Один класс
правил использует линейно возрастающий приоритет [Клейнрок,
1970]. Каждому процессу при входе в систему присваивается некий
приоритет. Приоритет возрастает с коэффициентом а во время ожи-
дания в очереди готовых процессов и с коэффициентом Ь во время
выполнения. В зависимости от выбора а и b получаются разные пра-
вила планирования. Например, если 0<я<Д то очередь обслу-
живается в порядке поступления (FCFS). Если то полу-
чается обслуживание в противоположном порядке (LCFS х)). Все
возможные правила этого класса, которые можно получить, варьи-
руя параметры а и 6, впервые описал Клейнрок. Один алгоритм из
этого класса будет рассмотрен в следующем разделе.
Можно придумать много вариантов правила линейно возраста-
ющего приоритета, хотя очень немногие из них изучены. Например,
коэффициенты а и & могут зависеть от внешнего приоритета, т. е. от
затрат, которые пользователь считает приемлемыми. Можно выби-
рать и нелинейные функции. Можно устроить, чтобы приоритет
убывал по линейному закону с течением времени. Когда достигается
некое максимальное время, приоритет скачком возрастает до неко-
торой большой величины. Это благоприятствует коротким процессам,
и при этом соблюдается условие, что ни одному процессу не придет-
т) По первым буквам «last-come-first-served», что означает «последним при-
шел — первым обслужен».— Прим, перев.
ся ждать обслуживания слишком долго. Подобным же образом можно
дополнить правило SJF, так чтобы длинные процессы, проведя не-
которое время в системе, начинали получать добавочный приоритет.
Избранный способ вычисления приоритета в большой степени опре-
деляется особенностями того типа процессов, с которыми имеет
дело система.
Одна из важных задач планирования состоит в том, чтобы
обеспечивать занятость внешних устройств. С этой целью процес-
сам можно присваивать высокий приоритет в периоды, когда они
интенсивно используют ввод-вывод. Такого рода интенсивность
легко прослеживается, так как процесс обычно блокируется после
обращения к операции ввода-вывода. В частности, приоритет про-
цесса может быть обратно пропорционален длине промежутка вре-
мени с момента его последнего обращения к вводу-выводу. Имеются
экспериментальные данные, свидетельствующие о том, что операции
ввода-вывода обычно бывают сконцентрированы в отдельных частях
программ. Применяя стратегию HPF, основанную на интенсивности
ввода-вывода, можно обеспечить занятость периферийных устройств
в течение большой доли времени, так как процессам, больше других
использующим ввод-вывод, легче получить в свое распоряжение
процессор.
Очевидно, что количество различных правил вычисления прио-
ритета практически не ограничено. Несмотря на то что стратегия
приносит желаемый результат, обеспечивая большинству процессов
хорошее обслуживание, она дает и побочный эффект: заставляет
процессы с низким приоритетом долго ждать. В некоторых системах
это неприемлемо. Например, в системах с разделением времени поль-
зователю гораздо удобнее яолучать по одной секунде машинного
времени каждые пять секунд, чем двенадцатиминутный интервал
каждый час. Методы HPF не могут обеспечить такой вид обслужи-
вания. Это приводит нас ко второму важному классу правил плани-
рования, так называемым «круговоротам».
3.3.2. Круговорот
Простой круговорот х) (RR) не использует никакой статической
или динамической информации о приоритетах. Первый процесс из
очереди готовых процессов получает квант времени длиной в q се-
кунд, а затем отправляется снова в конец очереди, если только он себя
не заблокирует. Если в очереди имеется К процессов, то каждый
процесс получает q секунд из каждых Kq секунд процессорного вре-
мени. Следовательно, каждый процесс как бы выполняется процес-
сором, скорость которого равна 1/К скорости физического процес-
х) В оригинале «round robin».— Прим, перев.
сора. Поэтому длина очереди — это важный параметр, определя-
ющий быстроту продвижения процессов.
Величина кванта q определяет, насколько равномерно распре-
делено время процессора по коротким периодам. Если время q бес-
конечно, то метод круговорота сводится к стратегии FCFS. Так
как процессы, как правило, все время то входят в очередь, то поки-
дают ее, большая (конечная) величина кванта может случайно бла-
гоприятствовать одним процессам в ущерб другим. Например, если
четыре новых процесса поступают в очередь в тот самый момент,
когда некоторый процесс заканчивает свой квант, то получение им
следующего кванта отодвинется на 4q секунд. С другой стороны,
может случиться, что какому-то процессу повезет и многие стоявшие
перед ним в очереди процессы окажутся заблокированными, что
сократит ему время ожидания в следующем круге. Такие случай-
ные эффекты сглаживаются по мере уменьшения q, так как ве-
роятность блокировки процесса или поступления нового в течение
одного кванта становится малой.
С уменьшением q улучшается обслуживание более коротких
процессов. Когда q очень мало, все готовые процессы обслужи-
ваются одинаково и время ожидания прямо пропорционально объе-
му требуемых услуг. Однако можно выбрать q слишком малым. Для
квантов «разумной» величины можно пренебречь временем, необхо-
димым для переключения процессора с одного процесса на другой.
Если же q — величина того же порядка, что и время переключения,
то задержка при переключении становится заметной. В самом деле,
если время q слишком мало, то система может потратить на переклю-
чение процессов больше времени, чем на их выполнение. Вот почему
при круговороте надо брать квант времени средней величины, чтобы
накладные расходы, связанные с переключением, не. оказались
чересчур высокими.
Метод круговорота часто применяется в системах с разделением
времени, рассчитанных на большое число пользователей. Такие
системы должны, как правило, гарантировать каждому процессу
приемлемое время ответа. Иначе говоря, пользователи ожидают,
что независимо от величины кванта их будут обслуживать по мень-
шей мере один раз каждые несколько секунд. Если q постоянно и в
очереди К процессов, то время ответа приблизительно равно Kq.
Для больших К это может быть слишком долго. Определенное время
ответа можно гарантировать, если применить круговорот, ориенти-
рованный на цикл. В этом методе выбирается время цикла для
очереди готовых процессов, равное максимальному Достижимому вре-
мени ответа. Величина кванта вычисляется в начале каждого круга
прохождения очереди путем деления времени цикла на количество
процессов в очереди. Процессы, вновь поступающие во время цикла,
задерживаются до окончания цикла, прежде чем будут поставлены
в очередь. Если очередь слишком длинная, то потери на переклю-
чение могут быть заметными, так как q будет совсем маленьким.
Эту проблему можно урегулировать, задав минимальную величину
кванта. При сильной загрузке системы пострадает время ответа,
но по крайней мере издержки на переключение останутся на низком
уровне.
Существует множество других разновидностей круговорота.
По одному из правил, называемому круговоротом, со смещением,
каждому процессу предоставляется квант, величина которого за-
висит от внешнего приоритета процесса. Каждому процессу соот-
ветствует своя длина кванта, так что процесс продвигается со ско-
ростью, пропорциональной его приоритету. Можно придумать ана-
логичные правила, основанные на других составляющих приоритета,
таких, как распределение ресурсов, интенсивность ввода-вывода и
ожидаемое время обслуживания. Другой алгоритм круговорота
получается из схемы линейно возрастающего приоритета Клейн-
рока (разд. 3.3.1). Если параметры а и b таковы, что 0^Ь<а, то в
результате получается правило планирования, которое называется
«эгоистическим» круговоротом. Войдя в систему, процесс ждет, пока
его приоритет не достигнет величины приоритета работающих про-
цессов. Затем он выполняется в круговороте с другими работающи-
ми процессами. Поскольку приоритет выполняемых процессов уве-
личивается с коэффициентом Ь<а, ожидающие процессы долж-
ны их в конце концов догнать. И «эгоистический», и простой
круговороты более благоприятны для коротких процессов, чем
стратегия FCFS, просто потому, что короткие процессы полу-
чают с каждым квантом большую долю своего общего времени.
При &—О «эгоистический» круговорот фактически сводится к
простому.
Имея несколько очередей готовых процессов, система может
извлечь выгоду из характера распределения времен работы. Пусть,
например, известно, что если процесс не закончился в течение трех
квантов времени, то с вероятностью 85% он не закончится, пока
не получит 12 квантов. Этим свойством времен работы процессов
можно воспользоваться, применяя две очереди готовых процессов:
ведущую и фоновую. Каждый процесс проходит через три кванта в
ведущей очереди. После третьего кванта он сбрасывается в фоновую
очередь. Процессор тратит большую часть своего времени на вы-
полнение процессов из ведущей очереди, обеспечивая таким обра-
зом отличное обслуживание коротких процессов. В одном из алго-
ритмов, ориентированных на цикл, процессам из ведущей оче-
реди предоставляется фиксированный квант времени. Если по-
сле того, как поработали все процессы ведущей очереди, до кон-
ца цикла еще остается время, то оно используется для выпол-
нения фоновых процессов. Такую систему с двумя очередями
можно обобщить до многоуровневого метода очередей с обратной
связью.
3.3.3. Очереди с обратной связью
В основном алгоритме очередей с обратной связью (FB г)) исполь-
зуется п очередей, каждая из которых обслуживается в порядке
поступления. Новый процесс, входя в систему, попадает в первую
очередь. После получения одного кванта он поступает во вторую
очередь. После получения каждого последующего кванта он пе-
реходит в очередь со следующим номером. Время процессора пла-
нируется так, что он обслуживает непустую очередь с наименьшим
номером. В методе FB вновь поступивший процесс неявно получает
высокий приоритет и выполняется подряд в течение стольких кван-
тов времени, сколько успеет пройти до прихода следующего процес-
са, но не больше, чем успел проработать предыдущий. Правило FB
обеспечивает лучшее, чем при круговороте, обслуживание коротких
процессов, не требуя предварительной информации о времени выпол-
нения. Однако работа с несколькими очередями может повлечь
большие издержки времени в начальный период, особенно если
величина кванта мала.
Один из способов уменьшить требуемое количество очередей
представляет собой обобщение метода ведущей и фоновой очередей,
ориентированного на цикл. Вместо того чтобы менять очередь после
каждого кванта, позволим процессу фиксированное число раз про-
ходить каждую очередь, прежде чем опускаться на следующий,
более низкий уровень приоритета. При этом очереди, упорядочен-
ные по правилу FB, обслуживаются по правилу круговорота внутри
каждой очереди, и по тому же правилу распределяется время про-
цессора между очередями. Хотя при этом различие между процес-
сами разной длины проводится уже не так четко, накладные рас-
ходы, связанные с содержанием очередей, уменьшаются.
При стратегии FB пользователи могут извлечь для себя некото-
рую выгоду, разбивая свои задания на короткие процессы. Время
обслуживания всех частей будет значительно лучше, чем если пред-
ставить задание в виде одного длинного процесса.
Основное преимущество очередей с обратной связью и круговоро-
та по сравнению с обслуживанием по наивысшему приоритету сос-
тоит в том, что первые два метода позволяют хорошо обслуживать ко-
роткие задания, не требуя предварительной информации о времени
выполнения процесса. С другой стороны, в тех случаях, когда при-
оритет вычисляется как функция от ресурсов, выделяемых процессу,
часто желательно отдать предпочтение процессам с высоким прио-
ритетом, чтобы увеличить загруженность ресурсов. Если жела-
тельно, чтобы учитывалась информация о приоритетах, то можно
использовать смешанные правила, которые сочетают использова-
ние динамических и статических данных, например круговорот со
смещением.
1) От «feedback», что означает «обратная связь».— Прим, перев.
3.4. Многоуровневое планирование
В предыдущих разделах мы рассмотрели разнообразные схемы
планирования. Для большинства из них требуется работа с очере-
дями, переключения процессов, а иногда и вычисления приоритетов
и величины квантов. В этом разделе мы изложим общий метод реали-
зации правил планирования, который эффективно организует вы-
числения, обеспечивая достаточную гибкость в принятии решений
при планировании.
3.4.1. Реализация планировщика процессов
В большинстве систем процессоры взаимодействуют посредством
прерываний. В центральном процессоре прерывание происходит,
когда истекает интервал, отсчитываемый реле времени, или когда
заканчивает работу канал, или когда выполняемая программа
пытается произвести ввод-вывод. Когда происходит прерывание,
центральный процессор передается супервизору (стержню) системы.
Супервизор выполняет некоторое действие, такое, как запуск
канала, разблокирование процесса или создание нового процесса,
а затем возвращает процессор готовому процессу из очереди. Так
как прерывания происходят часто, невыгодно выполнять очень
много команд каждый раз при предоставлении процессора очеред-
ному готовому процессу. Однако важно сохранять информацию,
касающуюся текущего состояния процессора, а также выполнять
некоторые вычисления, связанные с приоритетом и величиной кван-
та. Следовательно, одна из задач заключается в том, чтобы приду-
мать такой метод работы с очередью готовых процессов, для
которого эти вычисления нужно было бы делать лишь изредка.
Ключевой принцип, лежащий в основе метода, состоит в том, что
операции, которые встречаются часто, должны занимать меньше вре-
мени, чем те, которые встречаются редко. Этот принцип, пронизываю-
щий все построение операционных систем, особенно удобен в примене-
нии к алгоритмам планирования, где операции разбиваются на уров-
ни в зависимости от частоты выполнения. Рассматриваемый здесь
метод многоуровневого планирования реализуется как система, состоя-
щая из трех уровней: диспетчера, краткосрочного планировщика и
долгосрочного планировщика. Диспетчер вызывается после того, как
обработка прерывания завершена. Он выбирает следующий подле-
жащий выполнению процесс из очереди готовых процессов. Так как
диспетчер работает очень часто, он должен быть совсем коротким.
В лучшем случае он должен только взять первый процесс из очереди
и предоставить ему процессор. Краткосрочный планировщик вызы-
вается, чтобы вставить готовый процесс в очередь [Бринч Хансен,
1971]. Хотя этому планировщику приходится, быть может, анали-
зировать состояние процесса, уточнения приоритета на этом уровне
должны быть сведены к самому минимуму. Процессы ставятся в оче-
редь часто, возможно, каждые несколько миллисекунд. Поэтому вне-
сение любых сложных изменений в состояние процесса следует оста-
вить долгосрочному планировщику. Долгосрочная корректировка,
которая делается не так часто, может быть более сложной. Для вы-
числения нового приоритета может использоваться информация
о состоянии процесса, например о предоставленных ему ресурсах.
Так как долгосрочный планировщик вызывается только раз в нес-
колько секунд, он может позволить себе потратить на работу нес-
колько миллисекунд.
Преимущество такой трехуровневой организации состоит в том,
что она локализует издержки времени, связанные с планированием.
Если приблизительная частота вызовов каждого уровня известна
заранее, то ограничения на допустимый объем вычислений на каж-
дом уровне тоже можно указать заранее. Всякий предполагаемый
алгоритм планирования должен удовлетворять временным ограни-
чениям на каждом уровне.
3.4.2. Пример многоуровневого планирования
В разд. 3.3.2 мы говорили о скорости процесса в связи с пра-
вилом круговорота. Было показано, что скорости процессов мож-
но варьировать, регулируя величину кванта для каждого процесса.
Тогда, чтобы вычислить скорость процесса, нужно разделить ве-
личину его кванта на время, которое требуется для того, чтобы один
раз пройти полный цикл очереди готовых процессов. Хотя такой
планировщик позволяет достаточно хорошо управлять скоростями
процессов, он не дает никаких гарантий относительно того, как час-
то процесс будет получать процессор. Рассмотрим систему, которая
осуществляет одновременно как пакетную обработку, так и работу
с разделением времени. Пакетной системе требуется 75% времени
процессора, но безразлично, когда она их получит. Системе разде-
ления времени нужно только 25% времени, но она должна полу-
чать процессор по крайней мере один раз в секунду. Далее, в обеих
подсистемах выполняется множество процессов, и каждый из них
должен удовлетворять временным ограничениям породившего его
задания. К примеру, ни один из процессов, участвующих в разде-
лении времени, нельзя не допускать к процессору в течение более
чем одной секунды. Планировщики, ориентированные на цикл, мо-
гут гарантировать крайний срок, а именно время цикла. Но этот
крайний срок обязательно будет одинаковым для всех процессов.
Если в системе предусмотрена также работа в реальном масштабе
времени и соответствующие процессы должны получать пр двадцать
микросекунд каждые десять миллисекунд, то время цикла при кру-
говороте должно было бы равняться десяти миллисекундам. Ясно,
что это неосуществимо, так как издержки на переключения про-
цессов стали бы недопустимо высокими. Решение этой проблемы,
предложенное ХорнингохМ для проекта SUE, включает использова-
ние многоуровневого планировщика.
В предлагаемой системе планирования каждому процессу P(i)
ставится в соответствие длина кванта q(i) и предел ожидания х) /(f).
Предел ожидания показывает, как часто процесс должен получать
свой квант. Процесс P(i) должен получить q(i) секунд времени про-
цессора в течение /(f) секунд после входа в очередь готовых про-
цессов. Скорость процесса, определяемая как s (f)=g(f)//(f), соот-
ветствует доле процессорного времени, которую этот процесс полу-
чает, когда он не заблокирован. Например, для простого правила
круговорота, ориентированного на цикл, f(i)=f — время цикла
очереди, и если всего имеется К процессов, то каждый процесс
получает квант, равный f/K
При постановке в очередь процесса P(i) для него вычисляется
крайний срок Т(1) — момент, до наступления которого ему следует
получить свой квант. Если P(f) ставится в очередь в момент времени
/(f), то = Затем очередь готовых процессов упорядо-
чивается по крайним срокам получения квантов. Первый процесс
из очереди выполняется, пока не кончится его квант или пока он не
заблокируется. Если к моменту окончания кванта процесс оста-
нется незаблокированным, он возвращается в очередь и для него
вычисляется новый крайний срок.
Объем программ, необходимый для реализации такого трех-
уровневого планировщика, соответствует временным ограничениям
каждого уровня. Диспетчеру нужно только выбрать первый эле-
мент очереди. Краткосрочный планировщик должен заново вычис-
лить крайний срок получения кванта и вставить процесс в очередь.
Долгосрочный планировщик может уточнять значения /(f), 7(f) и
s(f) для каждого процесса. И еще одно свойство этой простой трех-
уровневой системы: ее можно настроить так, чтобы получились мно-
гие из ранее упомянутых «алгоритмов планирования. Например,
правило круговорота получается, если положить q(t)=q,
для всех процессов. Если q(i) для каждого процесса превышает не-
обходимое этому процессу время процессора, то алгоритм сводится
к правилу FCFS. Подобным же образом можно получить и другие
правила.
Планировщик системы SUE изящен, но все же весьма ограничен.
Он построен в предположении, что все процессы находятся в основ-
ной памяти. В пакетной мультипрограммной системе это может
быть справедливо, однако для системы разделения времени это, во-
обще говоря, неверно. В большинстве систем разделения времени
в основной памяти есть место для нескольких процессов. Когда поль-
зователи подключаются к системе через терминалы, соответствую-
х) В оригинале «time frame», что означает «временная рамка».— Прим, перев.
щие процессы переносятся в основную память с периферийных уст-
ройств, вытесняя другие процессы из памяти на диск. Вопрос в
том, как остановить выполняемый процесс, чтобы на его место
можно было поместить другой. Ясно, что остановить его должен
какой-то другой процесс, но передача процессора новому процессу
может задержаться, так как для этого должен поработать долго-
срочный планировщик. Пока все процессы находятся в оператив-
ной памяти, все идет гладко. Как только они начинают перемещать-
ся то в память, то из нее, приходится изобретать другие способы
планирования.
3.5. Заключительные замечания
Алгоритмы планирования, изложенные в этой главе, представ-
ляют собой ряд приемов эффективного распределения времени про-
цессора между процессами, образующими очередь. Эти правила при-
менимы и к некоторым другим задачам распределения ресурсов в
операционных системах. Подход многоуровневого планирования
служит примером того, как методы планирования можно реализо-
вать с ограниченными издержками. Несмотря на то что эти приемы
известны, оптимальное планирование все еще остается для боль-
шинства систем недосягаемо высоким уровнем квалификации.
Каковы бы ни были реализуемые методы планирования, всегда
должен существовать способ доказать эффективность метода или
установить источник потери эффективности. Этого можно добиться,
анализируя систему или прослеживая все ее шаги, когда она уже
реализована. Обзор способов, которые применяются для оценки
производительности системы, мы отложим до гл. 9.
Задания
3.1. Рассмотрим алгоритм планирования по приоритетам с вытес-
нениями, причем приоритет каждого процесса меняется во времени.
Скорость изменения пропорциональна константе а, когда процесс
ждет, и константе Ь, когда он выполняется. Если имеется несколько
процессов с наивысшим приоритетом, то все они обслуживаются
в режиме разделения времени с очень малой величиной кванта.
Допустим, что на вытеснения не налагается никаких ограничений.
Исследуйте поведение алгоритма в полном диапазоне изменения ве-
личин а и b [Клейнрок, 1970].
3.2. Опишите подробно алгоритм планирования процессов в какой-
нибудь конкретной системе. Связано ли распределение памяти как-
либо с алгоритмом планирования?
3.3. Во что обходится простой центрального процессора в течение 10%
времени в вашей системе? Сравните эти издержки с другими основ-
ными расходами на содержание вычислительной машины.
3.4. Предположим, что у вас есть машина с единственным процес-
сором, причем вытеснения не допускаются. Придумайте алгоритм
планирования, который бы минимизировал среднее время ожида-
ния, если потребности в процессорном времени известны заранее.
Придумайте другой алгоритм, который будет минимизировать мак-
симальное время ожидания. Если бы были разрешены вытеснения,
как это повлияло бы на ваш алгоритм?
3.5. Как бы вы поступили в многопроцессорной системе: предоста-
вили бы одному из процессоров планировать работу всех остальных
или сами распределяли бы задания между разными процессорами,
которые тогда в свою очередь могли бы осуществлять свое собствен-
ное планирование? Обсудите преимущества и недостатки каждой
схемы.
3.6. Во многих теоретических работах принято допущение, что про-
межутки времени между моментами поступления заданий распреде-
лены по экспоненциальному закону. Проделайте эксперимент на
своей машине, чтобы проверить эту гипотезу.
3.7. Загруженность вычислительной системы в течение дня не оди-
накова. Проделайте эксперимент, чтобы определить изменение за-
грузки за день на вашей машине и представьте результаты на гра-
фике. Опишите в общих чертах набор средств, которые могли бы
помочь сгладить пики загрузки.
3.8. В большинстве аналитических моделей планирования принято
много допущений. Например, модель Севсика [1971] предполагает,
что
1) работа планируется на одном процессоре;
2) цель планирования — максимизировать предоставляемые ус-
луги;
3) функция потерь, связываемая с каждым запросом, отражает
снижение уровня обслуживания, вызванное задержкой его испол-
нения;
4) каждый запрос относится к определенному классу запросов,
для которого известно распределение случайной величины време-
ни обслуживания;
5) процесс, посредством которого вводятся новые запросы, из-
вестен для каждого класса запросов;
6) вытеснение незавершенного запроса требует фиксированного
количества процессорного времени.
Подвергните критике или подтвердите каждое из этих предполо-
жений с практической точки зрения. Какого рода эксперименты были
бы необходимы, прежде чем результаты анализа, основанного на
этих предположениях, могли быть применены на практике?
3.9. Постройте алгоритм планирования, который управляет заг-
рузкой и подбором заданий на основе текущего состояния системы.
Исследуйте его динамические свойства при помощи моделирования.
Думаете ли вы, что этот алгоритм быстрее может улучшить уравно-
вешенность системы, чем изменения в комплектации оборудования
на основании представленных заданий? Дайте обоснованный ответ.
3.10. Рассмотрим множество процессов, в котором взаимное исклю-
чение реализовано посредством семафоров. Если процесс Р теряет
процессор в момент выполнения критического участка, то все осталь-
ные процессы будут блокированы, пока Р не получит процессор
вновь. Обрисуйте способ, которым планировщик может избежать
остановки процессов в критических участках. Рассмотрите тот же
вопрос, используя другие механизмы связи, такие, как передача
сообщений или мониторы.
Глава 4
УПРАВЛЕНИЕ ПАМЯТЬЮ
4.1. Функции для управления памятью
Управление памятью можно представлять себе каю отображение
информации в память посредством трех функций [Деннинг и др.,
1971] (рис. 4.1):
1) именующей функции (91), однозначно отображающей данное
пользователем имя в идентификатор информации, к которой это
имя относится;
2) функции памяти (Юс), отображающей однозначно определен-
ные идентификаторы (т. е. программные адреса) в истинные номера
ячеек (т. е. адреса памяти), в которых они находятся [Деннинг,
1970];
3) функции содержимого (S, отображающей каждый адрес памяти
в значение, которое по этому адресу находится.
Имена. Однозначные Ячейка S
^идентификаторы" помята
пользователем г <
Рис. 4.1. Отображения в память (91 — именующая функция; Щ} — функция па-
мяти; 6 — функция содержимого).
Результат каждого из этих трех отображений зависит от времени.
Это значит, что он может меняться в продолжение всего времени об-
работки задания системой. Например, результат отображения 91
не устанавливается до тех пор, пока задание не будет «связано» с
системными модулями и файлами, которые в нем упоминаются. Ре-
зультат отображения £01 может быть зафиксирован после загрузки
задания. Однако при некоторых стратегиях распределения памяти
отображение Ю1 меняется в течение всего времени, пока задание на-
ходится в оперативной памяти. Ясно, что результат отображения
6 меняется каждый раз, когда выполняется команда записи в па-
мять.
4.1.1. Привязка
Действие, состоящее в закреплении результатов одного из упо-
мянутых отображений, называется привязкой. Время, когда проис-
ходит привязка отображения /, называется моментом привязки
отображения f. Привязка может происходить во время программи-
рования задания или в то время, когда его обрабатывает система,
например во время компиляции или загрузки. Иногда привязка
отображения происходит так часто, что естественнее считать, что
привязки вообще не происходит. Примером такого отображения
может служить функция содержимого Поскольку функцию ®
полностью определяет пользователь, с точки зрения системы она не
особенно интересна. А вот отображения ЭЯ и Э1 находятся в ведении
системы, а избранные изготовителями системы моменты привязки
являются важными ее характеристиками. Возьмем, например, функ-
цию памяти ЭЯ. Для достижения большей гибкости желательно, что-
бы привязка отображения ЭЯ происходила достаточно поздно, так
как это дает системе возможность перемещать задание в памяти, до-
биваясь ее максимальной загруженности. К сожалению, конструк-
ция некоторых машин такова, что реализация подобного подхода
обходится дорого. Хотя раннюю привязку отображения ЭЯ легко
реализовать, это сильно ограничивает возможности использовать
память равномерно. Аналогичные рассуждения применимы и к име-
нующей функции. При чтении последующих разделов читателю сле-
дует помнить о взаимосвязи между гибкостью и стоимостью реали-
зации всякой стратегии.
4.1.2. Именование
Данное пользователем имя может относиться к различным объек-
там в зависимости от контекста, в котором оно употребляется. Сис-
темы программного обеспечения повсеместно сталкиваются с проб-
лемой установления соответствия между именами и объектами. На-
пример, в языках программирования, имеющих блочную структуру
(таких, как АЛГОЛ), данное пользователем имя может относиться
к нескольким различным переменным в зависимости от того, в ка-
ком блоке оно употребляется. Для операционных систем контекст,
с которым обычно приходится иметь дело,— это текст программы
пользователя. Несколько пользователей могут дать одни и те же
имена различным файлам или процедурам. Операционная система
обязана поставить в соответствие каждому имени в каждом контек-
сте пользователя нужный объект.
Вообще желательно, чтобы различным программам было позво-
лено называть один и тот же объект соответственно различными име-
нами. Это часто бывает удобно при работе с файлами, когда различ-
ные пользователи могут обращаться к системным файлам по различ-
ным именам. Существенно также, что если имя используется для
ссылки на один и тот же объект в нескольких местах, то во всех слу-
чаях это имя должно быть связано именно с этим объектом. Первую
проблему — использование нескольких имен, относящихся к одному
файлу,— мы рассмотрим в гл. 6. Вторая проблема — привязка имен
к объектам, для которых они предназначены,— рассматривается в
следующем разделе.
4.1.3. Общая проблема объединения модулей
Рассмотрим программу, которая состоит из нескольких процедур
и структур данных, причем некоторые из них определены пользова-
телем как, например, программы на ФОРТРАНе или PL/I, а другие
определяются системой (как, например, компилятор с ФОРТРАНа
и обслуживающие программы). Каждая отдельно порожденная ком-
пилятором или ассемблером программа или структура называется
объектным модулем и начинается с относительного адреса 0. Моду-
ли работают совместно, т. е. один модуль может обращаться к про-
цедуре или иметь доступ к данным другого модуля. Такие обраще-
ния называются внешними ссылками. Например, процедура ПРОЦ1
из одного модуля может пожелать обратиться к процедуре ПРОЦ2
из другого модуля. Поскольку модули компилируются по отдельно-
сти,, процедура ПРОЦ1 не может «знать» адреса ПРОЦ2. ПРОЦ1
может знать только имя ПРОЦ2. Таким образом, прежде чем можно
будет загрузить всю программу в память, надо разрешить эту ссыл-
ку, т. е. нужно сообщить процедуре ПРОЦ1 адрес процедуры ПРОЦ2
внутри соответствующего модуля. Этот процесс разрешения ссылок,
называемый объединением модулей г), может быть осуществлен лю-
бым из трех способов:
1) программист может представить набор процедур, которые объ-
единяются во время компиляции;
2) предварительно скомпилированные программы объединяются
либо до загрузки, либо во время загрузки в память;
3) объединение откладывается до запуска программы на счет и
осуществляется системой автоматически в процессе счета.
В большинстве языков высокого уровня реализуется первый
способ, т. е. пользователю разрешено описывать много процедур,
которые могут обращаться друг к другу внутри единой программы.
Это означает, что процедуры (такие, как ПРОЦ1 и ПРОЦ2) объединя-
ет компилятор. Объектный модуль, порождаемый компилятором,
можно либо прямо загрузить в память, либо сначала объединить его
с другими, системными программами. Если модуль надо сначала
объединить с системными программами, то способ объединения
можно считать промежуточным между первым и вторым.
При втором способе объединение осуществляется как отдельный
шаг между компиляцией и загрузкой. Хотя объединение модулей и
х) В оригинале «linking». Мы будем иногда пользоваться также выражением
«установление (внешних) связей».— Прим, перев.
загрузку можно выполнять как отдельные шаги, все большее рас-
пространение получают одношаговые загрузчики, объединяющие мо-
дули. Такой загрузчик не только разрешает внешние ссылки, но и
заменяет все первоначальные, вычисленные относительно нуля адре-
са, приводя их в соответствие с адресами, с которых модули загру-
жаются. Эта операция называется настройкой на место1).
Третий способ, состоящий в том, что модули объединяются во
время выполнения программы, бывает полезен, когда имена некото-
рых из входящих в состав программы процедур не известны до на-
чала выполнения программы. Такое положение возникает всякий
раз, когда характер требуемых вычислений зависит от данных. Вмес-
то того чтобы объединять все подпрограммы, которые могут понадо-
биться, подпрограммы объединяются только при обращении к ним.
Поскольку этот способ очень близок к схеме распределения, пред-
лагаемой в разд. 4.6, мы отложим его описание до конца главы.
4.2. Способы объединения модулей
Сложность способов объединения модулей сильно зависит от обо-
рудования. В этом разделе мы предположим, что структура обору-
дования проста. Всякая группа объектных модулей объединяется в
один объединенный модуль в относительных адресах с началом в
нулевой ячейке. Поскольку кодировка объединенного модуля не
зависит от места, на которое он будет загружен, его называют пере-
местимым 2).
Когда модуль загружается в оперативную память, абсолютный
адрес его первого слова помещается в регистр настройки (или ба-
зовый регистр). Тогда, чтобы по ссылке на адрес вычислить абсо-
лютный адрес слова в памяти, нужно относительный адрес ссылки
сложить с содержимым базового регистра. Позднее мы рассмотрим
объединение модулей при других способах адресации.
4.2.1. Загрузчик, объединяющий модули
Загрузчик, объединяющий модули — это однопроходная про-
грамма, которая объединяет объектные модули, настраивает адреса
и физически загружает программу в оперативную память. Кроме
собственно текста программы и его длины, при каждом модуле для
загрузчика должна быть задана следующая информация:
1) имена, описанные в данном модуле, на которые могут ссылать-
ся другие модули;
х) В оригинале «relocation», что означает буквально «перемещение». В даль-
нейшем мы будем для краткости опускать слова «на место».— Прим, перев.
2) В оригинале «relocatable», т. е. допускающий настройку (relocation) на
место в памяти.— Прим, перев.
2) имена, не описанные в данном модуле, на которые есть ссыл-
ки в данном модуле (т. е. внешние ссылки);
3) адреса, которые следует вычислить заново в зависимости от
того, куда внутри объединенного модуля загружается данный мо-
дуль (например, адреса, вычисленные относительно начала этого
объектного модуля).
Работа загрузчика состоит в том, что он составляет таблицу имен,
содержащую все имена, на которые могут быть ссылки извне модуля.
Эта таблица каждому содержащемуся в ней имени ставит в соответ-
ствие запись, которая допускает одно из двух возможных толкова-
ний. Если имя описано в модуле, который уже загружен, то соответ-
ствующая запись в таблице содержит адрес этого имени относительно
начала объединенного модуля. Если объектный модуль, в котором
определено данное имя, еще не загружен, то запись в таблице
содержит ссылку на связный список адресных полей, в которых в
дальнейшем будет стоять адрес, соответствующий данному имени х).
Когда оно наконец встретится загрузчику, он просмотрит этот связ-
ный список и вставит этот адрес во все элементы списка. Все модули
последовательно загружаются в память один рядом с другим. От-
носительные адреса теперь отсчитываются не от нуля, и, следова-
тельно, их нужно сдвинуть на сумму длин модулей, которые были
загружены раньше данного. Затем в таблицу имен вносятся новые
сведения и каждая внешняя ссылка данного модуля либо разре-
шается, либо присоединяется к списку, соответствующему этому
имени. Когда вся программа загружена, таблицу имен можно или
уничтожить, или сохранить для отладки.
Дополнительные сведения о загрузчиках, объединяющих моду-
ли, можно найти в книгах Гира [1969] и Донована [1972].
4.2.2. Редактор связей
Разрешение внешних ссылок модулей и настройку абсолютных
адресов можно выделить в особый этап, независящий от загрузки.
Программа, выполняющая эти операции и называемая редактором
связей, объединяет объектные модули в один, называемый модулем
загрузки. Модуль загрузки содержит текст программы и информа-
цию, необходимую для настройки. А настройку и загрузку выпол-
няет затем другая программа, называемая загрузчиком.
4.2.3. Сравнение способов объединения модулей
У двуступенчатой обработки есть несколько преимуществ. Во-
первых, не нужно редактировать связи перед каждым запуском про-
граммы на счет. Это несколько сокращает издержки, связанные с
х) Этот связный список образуют адресные поля из различных объединяемых
модулей, содержащие внешнюю ссылку на данное имя.— Прим. ред.
выполнением программы. Второе преимущество относится к объему
необходимой оперативной памяти. Поскольку собственно загрузчик
менее сложен, чем загрузчик, объединяющий модули, он и меньше
по размеру. Таким образом, шаг выполнения задания, к началу ко-
торого нужно иметь в оперативной памяти загрузчик, при двусту-
пенчатом подходе требует меньше оперативной памяти. Третье пре-
имущество состоит в том, что с помощью редакторов связей можно
реализовать перекрытие программ в памяти, о чем будет рассказа-
но в разд. 4.4.
При двуступенчатом объединении и загрузке главное неудобство
связано со вводом-выводом. Редактор связей должен вывести модуль
загрузки, который затем снова вводится для загрузчика. Большин-
ство программ пользователей если и требуют, то лишь незначитель-
ных изменений перед загрузкой. Таким образом, выполняется много
лишних операций ввода-вывода, которые часто бывают наиболее
дорогими составляющими в обработке.
При двуступенчатом способе большая экономия получается за
счет того, что если программа не меняется, то объединение нужно
делать только один раз. Однако для тех пользовательских заданий,
которые будут запускаться на счет очень мало раз или часто подвер-
гаться изменениям, выгода от того, что не нужно объединять модули
при последующих запусках, очень мала по сравнению с расходами
на двуступенчатую обработку при отладке. Поэтому для задач, ко-
торые будут работать только один раз или часто подвергаться из-
менениям, обычно дешевле пользоваться объединяющим загрузчи-
ком.
В оставшейся части главы мы будем исходить из предположения,
что задание уже прошло этап установления связей и существует в
виде переместимого модуля загрузки, начинающегося с нулевого ад-
реса. Способ настройки зависит от того, какая схема распределения
памяти применяется в системе. Большинство схем распределения,
как и та, которую мы рассмотрели в этом разделе, настраивает мо-
дули простейшим образом. Поэтому мы можем сосредоточить вни-
мание на том, как объединенный модуль записывается в оперативную
память.
4.3. Распределение памяти
Принцип, по которому задачам выделяется память, называется
стратегией распределения памяти. Программа может выполняться
только тогда, когда ее команды и данные находятся в оперативной
памяти. Простейшая стратегия распределения заключается в том, что
задача целиком загружается в идущие подряд ячейки оперативной
памяти. Однако, поскольку в каждый момент работает только не-
большая часть задания, можно сэкономить память, поместив в опе-
ративную память только ту часть задания, которая выполняется в
данный момент. Остальные части задания находятся на периферий-
ном устройстве (например, на барабане) до тех пор, пока они не
понадобятся. При такой стратегии память используется более эф-
фективно, но перемещения частей задачи по мере надобности в
оперативную память и из нее приводят к дополнительным издерж-
кам. В последующих разделах мы проанализируем несколько стра-
тегий распределения, которые при определенных условиях улуч-
шают среднюю загруженность памяти, не приводя при этом к
большим накладным расходам.
4. 3.1. Привязка к месту в памяти
Функция памяти ЭЛ выделяет переместимому модулю загрузки
реальные ячейки памяти. При статическом распределении привязку
к памяти осуществляет либо программист или компилятор — до
загрузки, либо загрузчик — во время загрузки. Третий подход со-
стоит в том, что привязки ЭЛ вообще не происходит; это дает возмож-
ность перемещать задание в оперативной памяти во время работы.
Такая стратегия, называемая динамическим распределением памяти,
позволяет системе эффективно заполнять память. По мере того как
порции информации передаются в оперативную память и из нее,
между заданиями появляются зазоры, которые обычно слишком ма-
лы, чтобы их можно было использовать. Когда таких щелей много,
говорят, что имеет место фрагментация памяти. Если допускается
повторная привязка ЭЛ после загрузки, то, передвигая задания в
оперативной памяти, можно зазоры объединить в области, достаточ-
но обширные для того, чтобы разместить в них задания. Таким обра-
зом, динамическое распределение памяти расширяет возможности
системы в борьбе с фрагментацией памяти.
Ниже мы приводим узловые моменты привязки к памяти для
статического и динамического способов распределения по Деннин-
гу [Деннинг и др., 1971].
1. Программирование в абсолютных адресах. Программист ука-
зывает машинные адреса во время написания программы.
2. Программирование в символьных обозначениях. Компилятор
или ассемблер в процессе трансляции порождают адреса вместо
символьных имен. Привязка этих адресов к памяти может происхо-
дить следующими путями:
а) порождаемые адреса представляют собой фиксированные аб-
солютные адреса;
Ь) порождаемые адреса допускают настройку и при загрузке по-
лучают абсолютные значения, не меняющиеся на протяжении всего
времени работы данного модуля;
с) порождаемые адреса допускают настройку и получают абсо-
лютные значения при каждом обращении к ним.
Способы 1, 2а и 2Ь — статические в том смысле, что привязка к
памяти происходит до или во время загрузки модуля в оперативную
память. Первый способ служит примером объединения отображе-
ний 9)1 и 91 раз и навсегда. Такой подход широко распространен на
небольших машинах, которые не могут обрабатывать несколько за-
дач одновременно. При втором способе отображения 9)1 и 91 разделе-
ны. В способе 2а привязка 9)1 происходит сразу же после 91. Такой
подход часто используется в быстрых компиляторах. При этом эта-
пы компиляции и загрузки ускоряются ценой снижения эффектив-
ности объектной программы. Располагая команды по мере их поро-
ждения прямо в тех ячейках, где они должны будут находиться во
время работы объектной программы, можно устранить большую часть
накладных расходов, сопутствующих загрузке и установлению свя-
зей. В методе 2Ь, который применяется на большинстве моделей се-
рии IBM/360, привязка к памяти 9)1 происходит во время загрузки.
При таком порядке модули загрузки переместимы, они могут рабо-
тать в любом месте оперативной памяти, но, как правило, не пере-
двигаются в памяти после первоначальной загрузки. Реализуются
все три стратегии несложно.
Метод 2с по-настоящему динамический, так как привязки 9)1 к
памяти совсем не происходит. Стратегии распределения, в которых
применяется этот подход, будут рассмотрены ниже в этой главе.
Свойства вращающихся запоминающих устройств таковы, что,
если требуется перемещать информацию, то лучше всего передавать
ее блоками, сводя таким образом к минимуму накладные расходы.
Как отмечалось в разд. 1.1, когда запись читается с диска или бара-
бана, решающее значение имеет время поиска. То есть время, требуе-
мое для отыскания нужной записи, обычно значительно больше вре-
мени, затрачиваемого на передачу информации в оперативную па-
мять, и поэтому длина блока более или менее безразлична. Таким
образом, передавать информацию выгоднее крупными порциями.
Уменьшение числа поисковых операций с лихвой возмещает допол-
нительные затраты времени, связанные с передачей более длинных
блоков.
Каким конкретно образом задания разбиваются на блоки, за-
висит от принятой стратегии распределения памяти. Эти блоки мо-
гут соответствовать содержательным частям, таким, как процедуры,
или характеристикам физических устройств, например размеру до-
рожки барабана. Далее в этой главе мы будем считать все задания
переместимыми, а размер блока произвольным, если он не указан
явно.
4.4. Перекрытие программ в памяти
Два программных модуля можно располагать в одних и тех же
ячейках памяти, при условии что этим модулям не нужно будет
присутствовать в оперативной памяти одновременно и что для сохра-
нения информации принимаются необходимые предосторожности
[Панкхерст, 1968]. Иначе говоря, привязка к памяти ЭЛ выполняется
во время загрузки, причем допускается, чтобы в один и тот же адрес
памяти отображалось несколько адресов программы. Например,
пусть С — главная процедура, которая сначала обращается к про-
цедуре А, а затем, несколько позже,— к процедуре В. Тогда можно
разрешить, чтобы процедуры А и В занимали одно и то же место
в памяти, как показано на рис. 4.2.
В системах, где для настройки объединенного модуля отведен
только один регистр, обязанность обеспечить, чтобы при обращениях
главной процедуры С к процедурам А и В в ячейках 407<—70/С на-
ходилась нужная процедура, обычно возлагается на редактор связей
и загрузчик. Входная информация для редактора связей состоит из
программных модулей и описания перекрытий1), в котором указано,
какие процедуры совместно используют области оперативной памя-
ти. В этом случае редактор связей порождает специальные команды,
которые включают загрузчик каждый раз, когда происходит обраще-
ние к одной из перекрывающихся подпрограмм. Загрузчик вводит
вызванный модуль в оперативную память, если тот еще не загружен.
Таким образом, программные модули динамически передаются
по мере надобности в оперативнукгпамять и из нее во время работы
задания.
Применение перекрытий позволяет значительно уменьшить ко-
личество оперативной памяти, необходимой программе. Если в сис-
теме допускаются перекрытия, то в ней могут работать даже такие
программы, общий объем которых превосходит размеры оперативной
памяти. Рассмотрим, к примеру, систему с оперативной памятью
80/С и загрузчиком, занимающим 10/С Такая система может вы-
полнять задание, изображенное на рис. 4.2, хотя его общая длина
больше, чем величина оперативной памяти системы. Итак, большей
гибкости в распределении памяти можно добиться, создав более
сложные редактор связей и загрузчик, допускающие перекрытие
модулей.
Однако существуют еще две проблемы управления памятью, ко-
торые применение перекрытий не решает. Вспомним наше первона-
чальное допущение, что перекрывающимся модулям не требуется
присутствовать в оперативной памяти одновременно. В некоторых
случаях, например при обращениях к процедурам, зависящим от
данных, или рекурсивным процедурам, динамическое поведение про-
грамм таково, что нельзя заранее сказать, можно ли две данные про-
цедуры сделать перекрывающимися. Другими словами, программист
может не знать, будут ли две данные процедуры обращаться друг к
Другу, и поэтому он не в состоянии дать описание перекрытий. По-
х) Наряду с термином «перекрытие» в литературе встречается также термин
«оверлей» от английского «overlay».— Прим, перев.
40 К
Procedure
Call A
СаП В
End*
Procedure A
End A
30K
Procedure В
End В
30K
W)
Здесь находится
лидо процедура А,
л и до процедура В —
д зависимости от того,
какая из них в данный
Момент выполняется
(с)
Рис. 4.2. Пример перекрытия частей программы в памяти, (а) Набор процедур, од-
на из которых обращается к другим. (Ь) Процедуры размещены последовательно,
(с) Процедуры размещены с перекрытием процедур А и В в области 40К —70/С.
(d) Схема перекрытий, на которой показано, что процедуры А и В занимают одну
и ту же область памяти 407С— 70/С.
скольку описывать структуру перекрытий для редактора связей обя-
зан программист, этот прием становится непригодным, когда поведе-
ние программ непредсказуемо.
До сих пор мы предполагали, что количество оперативной памя-
ти, которая может быть выделена задаче, известно заранее. Но объем
доступной оперативной памяти может динамически меняться во вре-
мя работы задания, и это ведет к другой важной проблеме перекры-
тий. По мере того как количество загруженных в систему модулей
возрастает, память загромождается. Доля памяти, выделяемая за-
данию, уменьшается, и в результате структура перекрытий какого-
нибудь задания может не поместиться в выделенной ему порции
памяти. Однако, возможно, имеются другие процедуры, принадлежа-
щие другим заданиям, которые могут перекрываться с первым зада-
нием. Программист никак не может знать это заранее. И наоборот,
когда машина слабо загружена, быть может, нет необходимости тра-
тить дополнительное время на динамическое перекрытие, поскольку
в распоряжении задания имеется достаточно памяти. Суть пробле-
мы в том, что программа должна использовать память по-разному в
зависимости от состояния системы, на которой она работает. Кроме
того, система должна иметь право оптимизировать распределение
памяти между всеми заданиями. Поскольку отдельный пользователь
не может предвидеть степень загруженности системы или поведение
других программ, применение метода динамического перекрытия
не может существенно улучшить использование всей памяти.
4.5. Попеременная загрузка заданий
Метод перекрытий предполагает, что если уж задание получило
область в оперативной памяти и было загружено, то оно будет на-
ходиться в этой области, пока не окончится. Иначе говоря, привязка
к памяти ЭЛ происходит во время загрузки. Помимо трудностей, свя-
занных с необходимостью предугадывать и максимальную потреб-
ность задания в памяти, и объем памяти, которая будет доступна для
распределения, это условие приводит к еще двум нежелательным ре-
зультатам. Первый из них связан с загруженностью памяти. Допус-
тим, что память некоторой мультипрограммной системы распределе-
на между заданиями, как это показано на рис. 4.3 (а). Если первым
закончится ЗАДАНИЕ 3, то новая схема распределения памяти
окажется такой, как на рис. 4.3(b). При этом из-за раздробленности
памяти система окажется не в состоянии выполнить новый запрос,
если потребуется выделить связную область размером в 150/С, даже
' несмотря на то, что в распоряжении системы будет находиться 150/<
свободной памяти. Очевидное решение этой проблемы состоит в том,
чтобы передвинуть ЗАДАНИЕ 2 на 50/< так, чтобы оно приблизилось
(а)
<Ь)
Рис. 4.3. Пример фрагментации памяти, (а) Первоначальное состояние памяти.
(Ь) Состояние памяти после окончания ЗАДАНИЯ 3.
вплотную к ЗАДАНИЮ 1. Но для этого потребовалось бы заново
выполнить привязку к памяти уже после загрузки.
Второй нежелательный результат связан с загруженностью дру-
гих ресурсов. Предположим опять, что память распределена между
тремя активными заданиями, как изображено на рис. 4.3 (а). Пусть
только одно из них, а именно ЗАДАНИЕ 2, работает в настоящий
момент с дисками. Закончив работу, ЗАДАНИЕ 2 отдает системе
диски и освобождает оперативную память. Ясно, что диски будут
простаивать до тех пор, пока в оперативную память не будет введе-
но новое задание, которое пользуется дисками. Допустим, что един-
ственное из ожидающих заданий (назовем его ЗАДАНИЕ 4), кото-
рому нужны диски, имеет длину 250/G К несчастью, в системе
имеется только 1507С свободной памяти, что недостаточно для ЗАДА-
НИЯ 4. Чтобы диски не простаивали, желательно было бы освобо-
дить место в оперативной памяти для ЗАДАНИЯ 4, убрав из нее од-
но из пока еще активных заданий — ЗАДАНИЕ 1 или ЗАДАНИЕ 3.
Ввод ЗАДАНИЯ 4 в оперативную память быстро повысит загружен-
ность дисков (т. е. уменьшит общее время простоев). Однако, как и в
случае с неблагоприятным распределением памяти, при этом потре-
бовалось бы переместить задание после загрузки, что означало бы
повторную привязку к памяти.
Одно из решений упомянутых выше проблем состоит в том, чтобы
позволить системе вводить в оперативную память и выводить из нее
задания целиком и после первоначальной загрузки. Этот метод,
называемый попеременной загрузкой х), можно реализовать при по-
мощи базового регистра. Как мы уже отмечали, предполагается,
что все задания представляют собой программы в относительных
адресах с началом в нулевой ячейке. Если машина устроена так,
что для получения истинного адреса надо к каждому встречающему-
ся в программе адресу прибавлять содержимое базового регистра,
то задания можно перемещать в оперативной памяти, не нарушая
их внутренней адресации: когда задание находится в оперативной
памяти и начинается с ячейки А, в базовый регистр заносится значе-
ние А.
Возможность перемещать программы после первоначальной за-
грузки помогает более успешно управлять памятью и равномерно
загружать ресурсы. Во-первых, когда память окажется раздроблен-
ной на маленькие связные области, как в примере на рис-. 4.3, мож-
но заново разместить в ней задания. Во-вторых, другие части систе-
мы могут работать с большей пользой, поскольку система в большей
степени распоряжается тем, каким заданиям и когда находиться в
оперативной памяти. Например, если все одновременно присутствую-
щие в памяти задания связаны с вводом-выводом, то одно из них
можно для уравновешивания загрузки системы заменить вычисли-
тельным заданием. Однако следует тщательно проверить, не сво-
дится ли экономия, полученная благодаря попеременной загрузке,
на нет издержками от перемещения заданий.
Разумеется, попеременная загрузка программ в память и вывод
из нее занимают много времени. Один из приемов, позволяющих
сократить издержки от попеременной загрузки, состоит в примене-
нии программ, допускающих параллельное использование. Если
большая программа, которой могут захотеть воспользоваться нес-
колько заданий одновременно (например, компилятор), оформлена
как простая процедура, для которой данные задаются в виде совер-
шенно самостоятельной порции информации, то в памяти всегда дос-
таточно держать только один экземпляр такой процедуры. Несколь-
ко заданий могут пользоваться этим единственным экземпляром,
обращаясь к нему каждое со своими собственными областями дан-
ных. Тогда выгонять из памяти и загружать в нее понадобится толь-
ко эти собственные области данных каждого задания, пользующе-
гося этой процедурой. Возможность параллельного использования
программы — важная идея, которая столь же полезна и при других
подходах к распределению памяти. Однако она только в тех случаях
помогает значительно сократить издержки от попеременной загруз-
х) В оригинале употребляются два термина: «swapping» и «roll-in-roll-out».—
Прим, перев.
ки, когда какую-то отдельную программу часто одновременно ис-
пользуют многие задания.
Основная трудность при попеременной загрузке состоит в том,
что приходится убирать из оперативной памяти целые задания. Обы-
чно эта мера оказывается более крутой, чем требуется на самом де-
ле. Если в данный момент работает одна из процедур какого-то за-
дания, то по крайней мере в течение некоторого времени в присутст-
вии большинства других его процедур в оперативной памяти нет
необходимости. Поэтому можно освободить дополнительную пло-
щадь в памяти, не выселяя задание целиком и не мешая ему работать.
Смысл приема перекрытий состоит в том, что часть задания изгоняет-
ся из оперативной памяти, но при этом возникает затруднение: про-
граммист должен знать заранее, какую часть программы можно без-
опасно убрать из памяти. Если объединить преимущество динами-
ческого метода попеременной загрузки с возможностью применять
его и к отдельным частям заданий, то задача распределения памяти
решается лучше. Далее в этой главе объектом нашего исследования
будут именно такие стратегии.
4.6. Сегментация
Большинство программ состоит из некоторого числа содержатель-
ных единиц, таких, как процедуры, области данных и програм-
мные блоки. Сегментация — это прием организации программ,
при котором адресная структура программы отражает ее содержа-
тельное членение. При сегментации пространство адресов каждой
программы подразделяется на называемые сегментами отрезки раз-
личной длины, которые обычно соответствуют содержательно раз-
ным частям программы. Например, сегментом может быть процеду-
ра или область данных. Слово из программы определяется адресом,
состоящим из двух частей: имени сегмента и адреса этого слова вну-
три сегмента, называемого смещением. Поскольку к программным
сегментам обращаются по именам, можно при распределении памя-
ти размещать сегменты в несмежных областях памяти. На самом де-
ле всем сегментам программы не обязательно находиться в оператив-
ной памяти одновременно. Некоторые из них могут располагаться на
периферийных устройствах. Если программа попытается обратить-
ся к сегменту, которого нет в оперативной памяти, то система вме-
шается и введет нужный сегмент из вспомогательной памяти в опе-
ративную. Хотя сегментированное пространство программы гораздо
легче поддается размещению, чем несегментированное, при от-
сутствии специального оборудования реализация двуступенчатой
адресации может обойтись довольно дорого. Поэтому большинство
систем, применяющих сегментацию, вычисляют адреса с помощью
аппаратного оборудования.
4.6.1. Реализация сегментации
В системе с сегментацией всякий адрес представляет собой пару
[s, d], где s — имя сегмента, ad — смещение. Каждому заданию или
процессу соответствует всегда присутствующая в памяти таблица
сегментов, в которой каждому сегменту данного задания соответ-
ствует одна запись. С помощью этой таблицы система отображает
программные адреса в истинные адреса оперативной памяти. Адрес
таблицы хранится в аппаратном регистре, называемом регистром
таблицы сегментов. В s-й г) строке таблицы находятся
1) признак (или бит присутствия), показывающий, присутст-
вует ли s-й сегмент в данный момент в памяти;
2) базовый адрес s-ro сегмента;
3) граница, указывающая количество ячеек, занимаемых дан-
ным сегментом;
4) биты защиты (не обязательные), используемые для контроля
способа доступа.
Чтобы добраться до слова [s, dl, надо с помощью регистра таблицы
сегментов обратиться к таблице сегментов (рис. 4.4). В s-й строке
таблицы указан адрес сегмента s в памяти. Его d-я ячейка содержит
искомое слово [s, d]. Следовательно, чтобы получить слово [s, d],
потребуется два обращения к памяти: одно к таблице сегментов и
одно к слову внутри сегмента. Поскольку сегменты бывают различ-
ной длины, не существует фиксированного верхнего предела для d.
Поэтому для того, чтобы помешать заданию обращаться за пределы
сегмента, необходимо знать значение границы. Во многих системах,
например в Burroughs В5700, описанные выше вычисления адреса
и проверка границы выполняются с помощью аппаратуры [Ор-
ганик, 1973].
Прежде чем система сможет вычислить адрес, аппаратным путем
проверяется признак присутствия сегмента в оперативной памяти.
Если сегмент присутствует, то адрес в памяти можно вычислить авто-
матически, как описано в предыдущем абзаце. Если сегмент отсут-
ствует в оперативной памяти, то происходит так называемое «пре-
рывание из-за отсутствия сегмента», т. е. вырабатывается аппарат-
ное прерывание, которое включает супервизорную программу
обработки таких ситуаций. Эта программа отыскивает нужный сег-
мент во вспомогательной памяти и вводит его в оперативную. Если
в оперативной памяти нет места для нового сегмента, то система ос-
вобождает его, выгнав один из находящихся в оперативной памяти
сегментов на периферийное устройство.
Если в какой-то момент система пожелает переключить свое вни-
мание на другую программу, она просто заменяет содержимое регис-
Э Здесь именем сегмента служит номер соответствующей ему строки.— Прим,
персе.
Рис. 4.4. Вычисление адреса при сегментации, ((b) — символическое изображе-
ние сумматора: результат = fj+f2+. . •+/„. Пусть 6(Х) —содержимое сло-
ва X. Тогда ($ (слово) = ($(6((S (регистр таблицы сегментов)+s)+d).)
тра таблицы сегментов на адрес другой таблицы сегментов, после
чего ссылки вида [s, d] интерпретируются в соответствии с новой
таблицей.
4.6.2. Преимущества сегментации
У сегментации пространства адресов программы имеется много
преимуществ по сравнению с традиционной абсолютной адресацией.
Во-первых система реализует перекрытия без каких бы то ни было
предварительных указаний программиста. Если в оперативной па-
мяти недостаточно места для всех сегментов данной программы, то
некоторые сегменты будут временно помещены во вспомогательную
память. В отличие от метода перекрытий сегментация делает возмож-
ным взаимное перекрытие областей отдельных программ. Если
какой-то программе потребовалось ввести в оперативную память но-
вый сегмент, то система может любой сегмент убрать из оператив-
ной памяти во вспомогательную. Вытесняемому сегменту не обяза-
тельно принадлежать той программе, для которой в оперативную
память вводится новый сегмент. Какой таблице сегментов соответст-
вует вытесняемый сегмент — не имеет значения, главное — чтобы
при переводе его во вспомогательную память в соответствующей
таблице сегментов изменялось значение признака.
Второе преимущество метода сегментации связано с объединением
модулей. В случае сегментации можно объектные модули програм-
мировать как сегменты. При этом существенно упрощается разреше-
ние внешних ссылок, так как объединяющей программе не нужно
иметь дело с абсолютными адресами. Фактически операция установ-
ления внешних связей сводится к просмотру таблицы для отыска-
ния адреса [s, d], соответствующего внешней ссылке. С загрузкой в
этом случае не связано никаких особых действий, за исключением
создания таблицы сегментов, в которой были бы указаны все сег-
менты. Кроме того, специальные загрузчики и редакторы внешних
связей, осуществляющие перекрытия, больше не нужны, поскольку
перекрытия теперь обеспечивает сама система.
Сегментация облегчает и организацию разделения параллельно
используемых программ. Для того чтобы такая процедура, занима-
ющая отдельный сегмент, могла работать в режиме разделения, нуж-
но внести информацию о том, где она расположена, в несколько та-
блиц сегментов. Следует особо позаботиться о том, чтобы, когда этот
сегмент перемещается на новое место в оперативной памяти или во
вспомогательную память, во все таблицы вносились соответствую-
щие поправки. Пример разделения сегментов будет рассмотрен в
одном из последующих разделов.
Если сегментация реализуется с помощью аппаратного обору-
дования, то большинство перечисленных выше преимуществ неза-
метны для пользователя. Всю сложную работу с адресными ссыл-
ками система берет на себя; пользователь ничего не знает о том, что
сегменты его программы расположены не подряд и даже не обязатель-
но все находятся в оперативной памяти. Однако вместе с тем сег-
ментация вносит и дополнительные трудности, связанные с управле-
нием памятью, которое должно обеспечить эффективное движение
сегментов через оперативную память и периферийные устройства.
Обсуждение методов управления сегментами мы отложим до гл. 5.
4.7. Страничная организация памяти
Страничная организация памяти — это такой способ управления
памятью, при котором пространство адресов памяти разбивается на
блоки фиксированной длины. При страничной организации все про-
странство оперативной памяти физически делится на отрезки рав-
ной длины, называемые физическими страницами. Программы и дан-
ные делятся на называемые страницами содержательные части того
же размера, что и физические страницы оперативной памяти х).
Таким образом, одну страницу информации можно загрузить в одну
физическую страницу.
4.7.1. Реализация страничной организации памяти
При страничной организации пространства оперативной памяти
адреса образуются подобно тому, как это делается при сегментации
пространства программных адресов. Каждый адрес представляет
собой пару [р, dl, где р — имя страницы, ad — смещение относитель-
но начала страницы р.
Каждому заданию ставится в соответствие таблица страниц, ко-
торая содержит список страниц, составляющих в совокупности это
задание. Запись в таблице страниц соответствует странице данного
задания. Каждая запись содержит
1) признак, показывающий, находится ли данная страница в опе-
ративной памяти;
2) указатель местоположения страницы (в оперативной или вспо-
могательной памяти);
3) биты защиты для контроля способа доступа (необязательно).
Кроме того, существует специальный регистр, называемый ре-
гистром таблицы страниц, в котором находится информация о
местоположении таблицы страниц, соответствующей выполняемому
в данный момент заданию.
Ниже, рассматривая алгоритм, по которому вычисляются адре-
са, мы будем иметь в виду схему на рис. 4.5. Если во время выполне-
ния программы встречается адрес [р, dl, то по содержимому регистра
таблицы страниц программа управления памятью находит таблицу
страниц. В р-й записи этой таблицы находится информация, ука-
зывающая на искомую страницу. Чтобы найти искомое слово, нуж-
но отсчитать d слов от начала этой страницы. Следовательно, для
того чтобы добраться до слова, требуется два обращения к памяти:
одно обращение к таблице страниц и одно — к самой странице. Как
и в случае сегментации, можно включить в систему специальное
оборудование для аппаратной реализации таблицы страниц, сокра-
тив таким образом задержку из-за двойного обращения к памяти
(например, система MULTICS [Органик, 1972]).
При каждом указателе местоположения страницы имеется приз-
нак, показывающий, присутствует ли уже данная страница в памя-
ти. Этот признак проверяется аппаратно перед вычислением адре-
са. Если его значение — «истина», значит, страница находится в
х) В оригинале «page frame» и «page», т. е. буквально «рамка страницы» и
«страница».— Прим, перев.
Результат
Рис. 4.5. Вычисление адреса при страничной организации памяти, ((b) — симво-
лическое изображение сумматора: результат = г‘1+/2+. . .+/п. б(слово) —
=6,(6(5(регистр таблицы страниц)+ p)-\-d).)
памяти и адрес вычисляется автоматически. Если значение призна-
ка — «ложь», то вырабатывается аппаратное прерывание, которое
служит для супервизора сигналом, что в оперативную память надо
ввести какую-то страницу. Это событие называется прерыванием
из-за отсутствия страницы. Кроме указателя и признака в табли-
це могут быть предусмотрены биты защиты. Они гарантируют, что
запрашиваемая страница будет использоваться в соответствии с
разрешенным для нее доступом (например, для чтения или для
записи). Работа с битами защиты может быть реализована аппа-
ратно, как и вычисление адреса.
Всякая страничная система должна придерживаться определен-
ных стратегий подкачек и вытеснения страниц. Первая стратегия—
это правило, по которому выбирается страница для ввода из вспо-
могательной памяти в оперативную. Вторая стратегия определяет,
какую страницу в оперативной памяти следует перекрыть, при ус-
ловии что другая страница уже подготовлена к вводу в оперативную
память. Цель стратегий выборки и вытеснения — организация дви-
жения страниц, т. е. их перемещения в оперативную память и из
нее. Эти стратегии столь же важны и при сегментации пространства
адресов, когда сегменты должны вызываться в оперативную память
из вспомогательной. Правила выборки и замещения страниц и сег-
ментов будут рассмотрены и проанализированы в гл. 5.
4.7.2. Преимущества страничной организации памяти
Многие преимущества, присущие сегментации пространства ад-
ресов программы, имеют место и при страничной организации прос-
транства адресов оперативной памяти. Сделанные выше замечания
относительно перекрытий при сегментации применимы в равной мере
и к страничной организации. Как и в случае сегментации, реализо-
ванное с помощью аппаратного оборудования вычисление адресов
делает сложную систему адресации понятной пользователю. Однако
фиксированная длина страниц приводит к важным различиям меж-
ду этими двумя методами.
Поскольку размер страниц фиксирован, страница может оказать-
ся недостаточно большой, чтобы в ней поместился целиком какой-
то содержательный раздел программы. Поэтому задача установления
внешних связей при страничной организации памяти не так проста,
как в случае сегментации программы. Но при фиксированной длине
страниц значительно упрощается распределение памяти. Посколь-
ку все страницы одинаковой длины, ввести в оперативную память
новую страницу легче, чем новый сегмент. Ее можно либо по-
местить в незанятую физическую страницу, либо вытеснить другую
страницу, чтобы освободилось место для новой. В любом случае для
того, чтобы освободить место для новой страницы, не требуется по-
новому располагать остальные страницы в оперативной памяти.
4.7.3. Фрагментация
Термин «фрагментация» означает наличие зазоров в памяти.
Когда пустые пространства возникают между блоками памяти, го-
ворят о внешней фрагментации, а когда «дыры» образуются внутри
самих блоков, говорят, что имеет место внутренняя фрагментация.
При фиксированной длине блоков (т. е. страничной организации
памяти) внешней фрагментации не бывает, так как при каждом уда-
лении блока он замещается другим блоком того же размера. Поэтому
между блоками нет зазоров, которые нельзя использовать. Но внут-
ренняя фрагментация имеет место, поскольку не всегда можно раз-
делить информацию на содержательные куски размером точно в стра-
ницу: например, одна из частей может занимать три с половиной бло-
ка, а половина блока останется незанятой. Вообще длина задания
Рис. 4.6. Внутренняя фрагментация, (а) Задание целиком. (Ь) Задание при разбие-
нии на страницы по 1500 слов; 1455 слов пустуют, (с) Задание при разбиении на
страницы по 500 слов; 455 слов пустуют. (При разбиении задания на страницы
часть памяти остается неиспользованной. Вообще, чем меньше размер страницы,
тем меньше внутренняя фрагментация.)
обычно не равна целому числу блоков. Поэтому, если придерживать-
ся правила, что в одной странице не могут содержаться данные или
программы, принадлежащие различным заданиям, то по крайней
мере один блок в каждом задании будет заполнен только частично.
Если блоки переменной длины, то, напротив, проблема внутренней
фрагментации решена, поскольку блоки можно «кроить» по размерам
информации. Но, к сожалению, при этом возникает внешняя фраг-
ментация, так как после удаления некоторого блока из памяти не
всегда возможно заменить его блоком той же длины. Таким образом,
дыры образуются по мере перемещения блоков в память и из нее.
Проблему фрагментации иллюстрируют рис. 4.6 и 4.7.
Если операционная система должна работать в условиях странич-
ной организации памяти, то при выборе размера страниц следует
учесть движение страниц и внутреннюю фрагментацию. Желатель-
но, чтобы страницы были большими (до определенного предела),
так как выгоднее перемещать один большой блок, чем несколько
блоков меньшего размера. При большой длине страницы требуется
мало страниц, чтобы разместить задание. При небольшом коли-
честве страниц в системе невелико и движение страниц, поскольку
при данном объеме памяти число перемещаемых в память и из нее
страниц невелико. Но большие страницы порождают большую вну-
треннюю фрагментацию. Рассмотрим, например, задание длиной в
1545 слов (рис. 4.6). Если длина страницы равна 1500 словам, то
потребуется две страницы, но при этом на второй странице будут
£ _______I
Пусто ВОК Пусто вок ЗАДАНИЕ 6 I ОСА'
1 оол
ЗАДАНИЕ} 1 125* ЗАДАНИЕ\ 125* Пусто 90*
ЗАДАНИИ 175* ЗАДАНИЕМ 140* I ЗАДАНИЕМ 140*
Пусто 35* Пусто 35*
ЗАДАНИЕЗ 10ОК ЗАДАНИЕЗ f 100* ЗАДАНИЕЗ I 100*
Пусто 75* Пусто 75* Пусто 75*
ЗАДАНИИ 125* ЗАДАНИЕМ 125* ЗАДАНИЕ* 125* LL
(а) (Ь) (с)
Рис. 4.7. Внешняя фрагментация, (а) Первоначальное состояние памяти*
(Ь) ЗАДАНИЕ 2 выводится, а ЗАДАНИЕ 5 вводится в память . (с) ЗАДАНИЕ 1
выводится, а ЗАДАНИЕ 6 вводится. (По мере того, как задания различной
длины то вводятся, то выводятся, зазоры в памяти то возникают, то исчезают.)
пустовать 1455 слов. Если длина страницы 500 слов, то потребуется
четыре страницы; при этом ожидаемое движение страниц возрастает,
но неиспользованными останутся только 455 слов. Иначе говоря,
существует равновесие между издержками, связанными с управле-
нием движением страниц, и издержками внутренней фрагментации.
Цель проектировщика — найти такой компромиссный размер страни-
цы, при котором влияние обоих этих факторов сводится, насколько
это возможно, к минимуму. В настоящее время распространенная
длина страницы колеблется приблизительно между 256 и 1024
словами.
4.8. Сегментация в сочетании со страничной
организацией памяти
Возможен подход, соединяющий в себе сегментацию и странич-
ную организацию, который состоит в том, что память разбивается
на страницы для каждого сегмента по его собственной таблице стра-
Рис. 4.8. Вычисление адреса при сегментно-страничном методе. (С(слово) = 6(d+
+(£(p+6(s+6 (регистр таблицы сегментов)))).)
Рис. 4.9. Ассоциативные регистры для быстрого доступа к страницам. (Ассоциатив-
ные регистры могут просматриваться параллельно, что дает возможность получить
адрес страницы по паре [s, р] за один командный цикл.)
ниц. Адреса при этом состоят из трех компонент: [s, р, d\. Первая
компонента — номер сегмента s (рис. 4.8). Вход в таблицу сегментов
осуществляется через регистр таблицы сегментов; s-я ячейка табли-
цы сегментов содержит базовый адрес и длину (т. е. границу) таб-
лицы страниц для этого сегмента. Вторая компонента адреса р опре-
деляет запись в таблице страниц, которая указывает на р-ю страни-
цу сегмента s. Затем, чтобы добраться до искомого слова, надо сме-
щение d прибавить к базовому адресу страницы. Итак, адрес [s, р, d]
может означать d-e слово р-й страницы s-ro сегмента того задания,
которое определяется содержимым регистра таблицы сегментов.
На такую трехкомпонентную ссылку требуется три цикла обра-
щения к памяти; это создает недопустимо большую задержку, даже
если поиск слова по адресу выполняется с помощью аппаратного
оборудования. Эту трудность можно обойти, если использовать груп-
пу ячеек памяти с быстрым доступом, называемых ассоциативными
регистрами. Эти регистры сопоставляют комбинациям [s, р] физи-
ческие места страниц (рис. 4.9). Основное свойство ассоциативных
регистров — то, что их можно просматривать параллельно. По за-
данной ссылке [s, р, d] ассоциативная память порождает указатель
страницы [s, р], если он имеется в одном из ассоциативных регистров.
Таким образом, количество требуемых циклов памяти сводится к
двум. Если комбинации [s, р] нет ни в одном ассоциативном регистре,
то происходит прерывание и супервизор заменяет содержимое од-
ного из ассоциативных регистров новой ссылкой Is, р]. Наблюдения
показывают, что ссылки распределяются в памяти неравномерно,
концентрируясь на нескольких интенсивно используемых страницах.
Поэтому для большинства адресных ссылок соответствующая ком-
бинация [$, р] будет найдена в ассоциативных регистрах.
Странично-сегментному методу присущи все преимущества и
сегментации, и страничной организации. Сегментация пространства
программных адресов дает возможность совсем нехитро реализовать
разделение и установление внешних связей. Страничная организа-
ция памяти позволяет, применяя несложную стратегию сегментации,
упростить распределение памяти. К тому же исключается внешняя
фрагментация. Но такая способность системы приспосабливаться
к различным требованиям достигается ценой трехкомпонентной
адресной ссылки. Однако при наличии соответствующего оборудо-
вания с ассоциативными регистрами можно добиться, чтобы стои-
мость дополнительных обращений к памяти оставалась в разум-
ных пределах.
4.9. Установление внешних связей
при странично-сегментном методе
4,9.1. Статическое установление связей
Как отмечалось в предыдущих разделах, процедуры, допускаю-
щие параллельное использование, могут работать одновременно
для нескольких заданий в режиме разделения. Однако установление
связей с такими процедурами часто оказывается весьма трудоем-
кой задачей. При странично-сегментном подходе существует удоб-
ный способ организации подобного разделения блоков. Рассмотрим
некоторую странично-сегментную систему и работающую в режиме
разделения процедуру Р, которая помещается в своем отдельном сег-
менте. Если пользователь хочет применить процедуру Р (т. е. об-
ратиться к ней как к подпрограмме), то разрешение внешней ссыл-
ки на процедуру Р в программе пользователя происходит следую-
щим образом: к таблице сегментов, соответствующей программе поль-
зователя, добавляется запись, содержащая указатель на таблицу
страниц процедуры Р. Кроме того, в ту же таблицу сегментов вклю-
чается отдельная область данных для процедуры Р. Такое дополне-
ние таблицы сегментов иногда выполняет редактор связей до заг-
грузки. Но как мы покажем в следующем разделе, это можно отло-
жить до тех пор, пока задание не станет выполняться.
4.9.2. Динамическое установление связей
Применение сегментации позволяет отложить установление свя-
зей с работающими в режиме разделения сегментами до выполнения
задания. Тогда можно разрешить, чтобы модули, с которыми на са-
мом деле будут установлены связи, изменялись в зависимости от
данных. В этом разделе мы рассмотрим одну из возможных реализа-
ций динамического установления внешних связей с использованием
странично-сегментной системы (рис. 4.10).
Во время компиляции вместе с каждым объектным модулем (т. е.
сегментом) задания в память записывается так называемый сегмент
связей. Каждой процедуре, упомянутой в объектном модуле, соот-
ветствует раздел этого сегмента связей. В такой раздел сегмента свя-
зей входят
1) символическое имя данной процедуры;
2) адрес таблицы страниц этой процедуры;
3) признак, показывающий, была ли уже установлена связь
между процедурой и заданием (начальное значение признака —
«ложь»);
4) указатель таблицы сегментов (его значение устанавливается
при первом обращении к подпрограмме, которое произойдет во вре-
мя выполнения).
Любая внешняя ссылка на некоторую процедуру должна указы-
вать на раздел сегмента связей, соответствующий этой процедуре.
Пусть работающее в данный момент задание А обращается к про-
цедуре FORTRAN. При выполнении этого обращения проверяется
признак, соответствующий процедуре FORTRAN в сегменте связей
задания. Если его значение — «ложь» (т. е. еще не установлена
связь процедуры FORTRAN с заданием А), то происходит аппарат-
ное прерывание, которое служит для системы сигналом, что надо
установить связь с процедурой. Получив запрос, операционная сис-
тема заводит в таблице сегментов задания А новую запись с информа-
цией о том, где расположена таблица страниц процедуры FORTRAN.
В соответствующую позицию в сегменте связей устанавливается
адрес той записи в таблице сегментов задания А, которая сопоставле-
на процедуре FORTRAN, а признаку присваивается значение «ис-
тина». Последующие обращения к этой процедуре будут идти через
Адрес 1-
Таблица страниц
„ Адрес Т
Страница программы
1 1 CALL FORTRAN [р',1] । CALL ALGOL [р',2] । CALL FORTRAN [p; 1 ] p
Признак Адрес 1
L1
(а)
База Граница
Адрес 2 L1
Адреса L2
Tad лица сегментов
(Ь)
Таблица сегментов задания
Адрес б
Таблица страниц процедуры
FORTRAN
(Р)
Рис. 4.10. Динамическое установление связей, (а) Страница программы и таблица
страниц сегмента, который обращается к работающим в режиме разделения сег-
ментам FORTRAN и ALGOL, (b) Таблица сегментов задания, таблица страниц
сегмента связей и страница сегмента связей до установления связей с сегментами
FORTRAN и ALGOL, (с) Таблица сегментов задания, таблица страниц сегмента
связей, страница сегмента связей и таблица страниц сегмента FORTRAN после
установления связи между заданием и процедурой FORTRAN.
сегмент связей и по найденной в нем информации — к нужной за-
писи в таблице сегментов. Вся эта работа, которая и составляет ус-
тановление связи между процедурой FORTRAN и заданием А, изо-
бражена на рис. 4.10.
Очевидное преимущество динамического установления связей
состоит в том, что можно в любое время перемещать работающую
в-режиме разделения процедуру (в нашем примере FORTRAN), не
меняя информации в связях. Сегмент связей задания имеет дело толь-
ко с расположением таблицы страниц процедуры FORTRAN,
которое, по нашему алгоритму, должно быть зафиксировано при
установлении связи. Страницы процедуры перемещаются в опера-
тивную память и из нее, как и страницы любой программы. Подоб-
ные алгоритмы можно использовать и в тех случаях, когда органи-
зация памяти не страничная; тогда не нужно оставлять таблицу
страниц разделяемой процедуры в оперативной памяти.
Заметим еще, что можно сочетать статический и динамический
методы установления связей. Например, модули пользователя мож-
но объединять до загрузки, а с разделяемыми модулями, такими, как
компиляторы и системные программы, можно устанавливать связи
динамически, когда они понадобятся. В системе MULTICS [Орга-
ник, 1972], применяющей странично-сегментную адресную струк-
туру, реализована возможность динамического установления свя-
зей, подобно тому как это изображено на рис. 4.10.
Задания
4.1. Во время выполнения процесса одна и та же процедура может
размещаться с перекрытием в различных местах оперативной па-
мяти. Перечислите задачи установления связей, возникающие при
перекрытии, в случае, когда эта процедура должна работать в ре-
жиме разделения между несколькими процессами. Как можно ре-
шать эти задачи?
4.2. Каковы преимущества сегментации по сравнению с динамичес-
ким перекрытием? Возможны ли такие обстоятельства, при которых
пользователь предпочел бы организовать свою программу в виде
перекрывающихся модулей, а не разбить ее на сегменты?
4.3. Опишите систему распределения памяти, реализованную на ка-
кой-либо машине, где используется исключительно принцип сег-
ментации, например Burroughs В5500.
4.4. В одних машинах существует адресация с точностью до слога
памяти; в других — кроме адресации до слова, возможна адреса-
ция до байта. Бывают и такие машины, где можно обращаться к
отдельным битам или произвольным последовательностям битов па-
мяти. Проанализируйте преимущества и недостатки каждого из пе-
речисленных способов адресации.
4.5. В некоторых системах те страницы, содержимое которых не ме-
нялось, пока они находились в оперативной памяти, не переписы-
ваются обратно на страничный барабан, когда их изгоняют из опера-
тивной памяти. Опишите в общих чертах, как можно программно
реализовать аппарат принятия таких решений.
4.6. Предположим, что в вашем распоряжении имеется машина, где
обращение к памяти происходит через посредство базового регистра,
который указывается в машинной команде. Есть также ассемблер,
порождающий программу в коде машины в абсолютных адресах.
Опишите последовательность шагов, которые, используя эти сред-
ства, позволили бы одновременно выполнить независимо скомпи-
лированные модули с возможностью перемещения их в памяти.
4.7. Необходимо ли, чтобы при сегментно-страничной организации,
описанной в разд. 4.8, таблица страниц каждого сегмента присутст-
вовала в памяти? Если нет, то опишите в общих чертах, как устроить,
чтобы это не требовалось. Почему таблицу сегментов необходимо
держать в оперативной памяти?
4.8. Постройте аппарат динамического установления связей для сег-
ментно-страничной системы, при которой таблицу страниц проце-
дуры, используемой в режиме разделения, не требуется всегда дер-
жать в памяти. Каковы преимущества такой системы?
4.9. Сделайте подробное описание аппаратного оборудования, на
котором реализована виртуальная память системы MULTICS. Объ-
ясните, как в этой системе выполняется установление связей.
4.10. Пусть требуется разместить в памяти большую разреженную
матрицу. Пусть вероятность обращения (чтения или записи) к эле-
менту (f, /) равна 0,5тах О. Как можно эффективно разместить
такую матрицу в линейной памяти в каждом из перечисленных
ниже случаев? Постарайтесь свести к минимуму расход памяти.
1. Все элементы одинакового размера, и ..этот размер мал.
2. Все элементы одинакового размера, и этот размер велик.
3. Элементы различного размера.
Глава 5
ВИРТУАЛЬНАЯ ПАМЯТЬ
5.1. Введение
Большая часть информации в системе хранится не в основной
памяти, а на весьма емких периферийных устройствах, таких, как
барабаны или диски. Однако для активного процесса непосредст-
венно доступна лишь та информация, которая записана в основную
память. Таким образом, можно ожидать, что процессу приходится
по ходу работы обращаться к вводу-выводу.
В системе с виртуальной памятью у каждого процесса создает-
ся иллюзия, что вся его информация находится в оперативной памя-
ти. Система поддерживает эту иллюзию, размещая некоторые из
не используемых в данный момент разделов программы и данных,
принадлежащих процессу, на периферийных устройствах. Если про-
цесс пытается обратиться к информации, которая находится не в
оперативной памяти, то автоматически вырабатывается прерывание,
возбуждающее супервизор. Супервизор перемещает нужную инфор-
мацию с периферийного устройства в память, и процесс получает
доступ к ней. Эта деятельность супервизора незаметна для процесса,
поскольку он приостанавливается до тех пор, пока передача инфор-
мации не будет завершена. По окончании передачи процесс продол-
жает работу, и, насколько ему «известно», информация, которая бы-
ла ему нужна, все время находилась в памяти. То, что информация
физически находится на одном или нескольких периферийных уст-
ройствах, скрыто от процесса.
В этой главе рассматривается построение и проводится анализ
методов распределения виртуальной памяти. Глава делится на три
раздела. Раздел 5.2 содержит описание специальных аппаратных
средств и способов организации памяти, которые имеются в распоря-
жении разработчика системы. В разд. 5.3 мы рассмотрим стратегии
распределения для двух методов реализации виртуальной памяти:
сегментации и страничной организации. Будут кратко сопоставле-
ны трудности, связанные с этими двумя методами. В разд. 5.4. пред-
ставлено несколько примеров поведения программ и системы при
наличии виртуальной памяти. Кроме того, здесь мы проанализи-
руем способы распределения и задачу поддержания равномерной
загрузки всей системы при применении стратегий, оптимизирующих
отдельные параметры.
5.2. Аппаратные средства
для виртуальной памяти
Существует множество хорошо известных устройств для хранения
и воспроизведения информации, например: регистры, память на ма-
гнитных сердечниках, барабаны, диски с неподвижными головка-
ми, диски с подвижными головками, магнитные ленты, перфоленты
и перфокарты. Предполагается, что читателю знакомы основные све-
дения о каждом из этих средств. Кроме того, существуют механизмы,
специально приспособленные для виртуальной памяти. В частнос-
ти, многоуровневая память и страничный барабан значительно пре-
восходят традиционные устройства с точки зрения экономической
осуществимости виртуальной памяти. В этом разделе исследуются
свойства этих двух видов организации памяти.
5.2.1. Многоуровневая память
Наиболее распространенный тип организации памяти — память,
состоящая из двух уровней (рис. 5.1). Первый уровень — это боль-
шая электронная память, например память на сердечниках, к ко-
торой может непосредственно адресоваться центральный процессор.
Второй уровень состоит из одного или нескольких весьма емких
периферийных электромеханических устройств, таких, как барабан,
диск и магнитная лента. Если нужной информации нет в оперативной
Рис. 5.2. Многоуровне-
вая память.
Рис. 5.1. Распространенный тип органи-
зации памяти-- двухуровневая память.
памяти (в системе со страничной организацией это соответствует от-
сутствию страницы), то прежде, чем к ней станет возможно обращать-
ся непосредственно, эту информацию следует перенести с периферий-
ного устройства в оперативную память. Такой подход применялся
почти во всех ранних проектах страничной и сегментной органи-
зации и до сих пор еще встречается на машинах небольшой и сред-
ней величины. Но возможностям больших быстродействующих ма-
шин со временем выполнения операции порядка всего 100 наносекунд
этот принцип двухуровневой организации не соответствует.
Когда быстродействующий центральный процессор работает со
слишком медленной для него памятью на сердечниках, значительную
часть времени он тратит на ожидание завершения выборки и записи
в память. Очевидное решение — очень быстрая большая память на
интегральных схемах — экономически неосуществимо при совре-
менной технологии, хотя есть основания полагать, что большая
монокристаллическая память может оказаться экономически осу-
ществимой в ближайшем будущем. Помимо того что такая память
дорого стоит, быстрому центральному процессору для эффективной
работы понадобилось бы, вообще говоря, один-два миллиона слов
оперативной памяти. Решением проблемы явилась разработка мно-
гоуровневой оперативной памяти [Кук и Лори, 1970].
На рис. 5.2 схематически изображена система с N уровнями па-
мяти [Мэттсон и др., 1970]. Запоминающее устройство M(N) —
электромеханическое. Все остальные уровни памяти — устройства
оперативной памяти с разными скоростями работы. Как правило,
при 1</ уровень М (0 быстрее, меньше и дороже (в расчете на одно
слово), чем уровень М (/’). В дальнейшем, говоря о многоуровневой
памяти, мы будем предполагать, что она разбита на страницы (т. е.
информация всегда передается блоками фиксированной длины).
Страница, которая находится в памяти f-го уровня, хранится
также на уровнях с большими номерами. Если центральный про-
цессор пытается обратиться к слову, которого нет на первом уровне,
то система начинает искать страницу, содержащую нужное слово,
на уровнях с большими номерами. Когда нужная страница найдена,
центральному процессору предоставляется возможность обращать-
ся к искомому слову, а страница переносится в более быстрые уровни
памяти, пока не достигнет наконец первого уровня. При переносе
страницы с более высокого уровня на более низки?! (более быстрый)
вытесняется какая-то старая страница. Обычно замещается та стра-
ница, которая дольше всех не использовалась. Идея состоит в том,
чтобы те страницы, которые чаще всего нужны в настоящее время, на-
ходились в более быстрых частях памяти.
Такая организация памяти реализована на нескольких крупных
машинах, в частности на IBM 370/168 и IBM 370/195 [Липтэй, 1968].
В реализации IBM первый уровень (так называемый кэш) содержит
от 16К до 32/< памяти на кремниевых регистрах со временем выборки
100 наносекунд, второй уровень содержит около миллиона слов па-
мяти на магнитных сердечниках со временем выборки, равным одной
микросекунде, а третий уровень, внешний,— это страничный бара-
бан. Интерфейс между кремниевыми регистрами и памятью на сер-
дечниках полностью реализован аппаратно, так что уровни памяти
невидимы для пользователя. В результате среднее время доступа
для этой трехуровневой памяти оказывается весьма близким ко вре-
мени доступа первого уровня.
5.2.2. Страничный барабан
Для ускорения передачи информации из вспомогательной памя-
ти в основную можно применять специальные устройства. Одно из
таких устройств, страничный барабан, дает значительное увеличе-
ние эффективности по сравнению со стандартной дорожечной орга-
низацией барабана.
Страничный барабан логически делится на п секторов и т доро-
жек, как показано на рис. 5.3. С каждой логической дорожкой свя-
зан набор головок чтения-записи; в одной логической дорожке
может содержаться несколько физических дорожек. Список запро-
са)
Дорожка Дорожка Дорожка
сов от процессов, ожидающих доступа к барабану, ведется по номе-
рам секторов, так что всего имеется п списков. Связь между этими
списками и устройством управления барабаном такова, что Z-й спи-
сок запросов связывается с барабаном как раз в то время, когда f-й
сектор проходит подголовками чтения-записи. При такой организа-
ции барабану редко приходится ждать какую-то заметную долю пе-
риода полного оборота, чтобы начать следующую передачу информа-
ции. Таким образом, загруженность соответствующего канала ста-
новится весьма высокой. Было показано, что классическая конструк-
ция барабана, не разделенного на секторы, с единственной очередью
запросов, обслуживаемой в порядке поступления, гораздо менее эф-
фективна, чем конструкция с секторами и несколькими списками
запросов. Принцип страничного барабана нашел применение также
и для дисков с неподвижными головками (по одной головке на доро-
жку). Исчерпывающий анализ работы страничного барабана можно
найти в статье Вайнгартена [1966].
5.3. Стратегии распределения ресурсов
при сегментации и страничной организации
С теоретической точки зрения сегментация и страничная орга-
низация — это логический и физический подходы, применяемые к
пространству программных адресов и пространству адресов памяти.
При практическом осуществлении теоретическая концепция сводит-
ся к проблемам размещения логических сегментов в физической па-
мяти и разбивки программ на страницы фиксированного размера.
Поэтому с точки зрения реализации основное различие между раз-
биением на страницы и на сегменты состоит попросту в том, что
в первом случае применяются блоки фиксированной длины, а во вто-
ром — блоки переменной длины. Следовательно, хотя страничная
организация и сегментация представляют собой очень разные кон-
цепции, задачи, возникающие при реализации этих двух методов,
так близки, что уместно обсудить их вместе.
При осуществлении сегментации или страничной организации
следует принимать во внимание три основных вопроса:
1) как распределить память каждого уровня;
2) какими критериями пользоваться, чтобы решить, когда надо
переместить страницу или сегмент из вспомогательной памяти в
оперативную;
3) какими критериями пользоваться при перемещении страницы
или сегмента из вспомогательной памяти в оперативную для реше-
ния вопроса о том, какие старые страницы или сегменты следует вы-
теснить, чтобы освободить место для новой страницы (сегмента).
На самом деле в случае страничной организации первая задача
не представляет никаких трудностей. Память делится на физические
страницы фиксированной длины, и система ведет таблицу страниц
и координат соответствующих физических страниц. Распределение
свободного места в памяти сводится в точности к определению того,
какие физические страницы в данный момент не используются.
При работе с сегментами переменной длины задача становится
более трудной. Существует несколько приемлемых стратегий рас-
пределения пространства, которые применяются, когда встречается
запрос на предоставление памяти. Эти методы будут описаны и со-
поставлены в разд. 5.3.1.
Вторая задача, т. е. принятие решения, какую страницу пере-
мещать из вспомогательной памяти, известна как проблема страте-
гии подкачек. Перемещение страницы из вспомогательной памяти,
до того как на нее по ходу вычислений фактически встретится ссыл-
ка, называется опережающей подкачкой J)- Пересылка страниц в опе-
ративную память только в том случае, когда ссылка приводит к пре-
рыванию из-за отсутствия страницы * 2), называется подкачкой по
запросу (или по требованию 3)). Вопрос о том, применять ли пред-
варительную подкачку или подкачку по запросу, мы рассмотрим в
разд. 5.3.2. „ -
Пусть известно, что определенную страницу надо переместить
из вспомогательной памяти в оперативную. Какую страницу следует
убрать, чтобы освободить место для новой? Предложено множество
стратегий вытеснения, в том числе одна, о которой доказано, что
она оптимальна (хотя реализовать ее невозможно!). В разд. 5.3.3
приведены некоторые хорошо известные правила вытеснения. В
разд. 5.4 мы оценим эти правила по отношению к определенным
принципам поведения программ и систем.
5.3.1. Стратегии распределения для сегментов
переменной длины
Допустим, что оперативная память выделяется блоками по /<
слов, где К, как правило, заключается в пределах от 8 до 2000. Об-
ласть памяти, предоставляемая по запросу, всегда должна состоять
из последовательных блоков. Например, в системе, где все блоки
памяти содержат по 1024 слова, задание, которому нужно 100/( слов,
запрашивает 100 последовательных блоков. Задача состоит в том,
чтобы найти стратегию распределения, которая позволяет хорошо
загрузить память при небольших издержках, связанных с работой
самих распределяющих алгоритмов.
Э В оригинале «prepaging».— Прим, перев.
2) Поскольку в этой главе прерывания, вызванные другими причинами, не
рассматриваются, мы будем иногда для краткости говорить просто «прерыва-
ние».— Прим, перев.
3) В оригинале «demand paging».— Прим, перев.
5.3.1.1. Список свободной памяти
В одном из простейших способов управления памятью применяет-
ся список свободных областей памяти, называемый списком пустот,
упорядоченный по возрастанию адресов. Каждая входящая в список
область свободной памяти содержит указатель на следующую об-
ласть списка и поле длины, в котором указано, сколько блоков со-
держит данная область (рис. 5.4). Когда ранее занятая область осво-
бождается, ее легко добавить к списку пустот. Элементы списка пус-
тот просматриваются последовательно; только что освобожденная
область вставляется в список с сохранением упорядоченности адре-
сов по возрастанию. Если предшествующая или последующая об-
ласть списка пустот (или обе) примыкают к вновь освобожденной,
то их можно объединить в одну свободную область.
Существуют две хорошо известные стратегии распределения па-
мяти из списка пустот: выбор первой подходящей области и выбор са-
мой подходящей области. Допустим, имеется запрос на область
длиной в k блоков. В обеих стратегиях отыскивается область под-
ходящего размера, первые k блоков выделяются для процесса, по-
славшего запрос, а оставшаяся часть области возвращается в список
пустот. В методе первой подходящей области список пустот просмат-
ривается сверху вниз и выбирается первая свободная область, у
которой длина ^k. В методе самой подходящей области используется
наименьшая область, у которой длина ~^k. За исключением случая,
Указатель Длина
Вершина
списка
пустот
Указатель Длина
777777
Указатель | Длина
Пусто | Длина
Рис. 5.4. Управление памятью с применением списка пустот. (Заштрихованы не-
пустые области,)
когда обнаруживается свободная область, состоящая в точности из k
блоков, метод самой подходящей области требует просмотра всего
списка пустот при каждом запросе. Поэтому для большинства запро-
сов алгоритм самой подходящей области работает медленнее алго-
ритма первой подходящей области. К тому же с помощью ряда мо-
делей было установлено, что метод первой подходящей области в бо-
льшинстве случаев плотнее заполняет память [Кнут, 1968]. Заметим,
что при обеих стратегиях, если нет областей, у которых длина ^k,
запрос остается неудовлетворенным. Чрезвычайные меры для таких
случаев мы рассмотрим в следующем разделе.
Другой способ организации списка пустот состоит в том, что его
упорядочивают по возрастанию длины области, а не по возрастанию
адресов. При этом алгоритм, отыскивающий первую подходящую
область, тот же, что отыскивающий самую подходящую. Еще ка-
кое-то время можно сберечь при распределении памяти, если завес-
ти в этом списке указатели {Pl, Р2, ..., Pi, ..., Рт}, где указатель
Pi указывает на первую область в списке, которая содержит от
iXc до (И~1)Х£ блоков (с— константа, зависящая от конкретной
реализации). Такой набор указателей может ускорить поиск, но
поддержание его в порядке может стоить довольно дорого. Главная
трудность этого метода состоит в том, что сложно вставлять вновь
освободившиеся области в список пустот и на это уходит много вре-
мени.
При третьей стратегии, называемой системой расщепления, па-
мять предоставляется блоками длины 2К Если размер памяти ра-
вен 25, то система ведет S-f-1 список, причем К-й список, LIST (К),
содержит блоки длины 2К. Первоначально все списки пусты, за ис-
ключением LIST(S), который указывает на первое слово памяти.
Чтобы выделить блок величины 2К, начинаем с просмотра LIST (К).
Если этот список непуст, то предоставляется один из его блоков.
В противном случае проверяется LIST (К+1). Если он непуст, то-
гда один из его блоков расщепляется на две половины, одна из кото-
рых выделяется процессу, а другая помещается в LIST (К). Если
LIST (7<+1) пуст, то процесс поиска продолжается до тех пор, пока
не будет найден непустой список. Если списки LIST (J) пусты при
всех J, для которых то запрос не удовлетворяется.
При такой схеме распределения адрес каждого блока величины
2К делится без остатка на 2К. Следовательно, для каждого блока раз-
мера 2К легко найти адрес того блока длины 2К+1, от которого он
был отщеплен. Как только два парных блока длины 2* — «двойняш-
ки», получившиеся в результате расщепления одного блока длины
2*+1, окажутся свободными, они объединяются. Объединение —
простая операция, поскольку «двойняшки» однозначно определяют-
ся адресами своих первых слов. В экспериментах с моделирова-
нием было обнаружено, что этот метод немного быстрее, чем алго-
ритм первой подходящей области. Но если размеры запрашиваемых
областей равномерно распределяются в интервале от 1 до 2s, то из-
за внутренней фрагментации системе расщепления требуется при-
мерно на одну треть больше места, чем при методе первой подходя-
щей области [Кнут, 1968].
5.3.1.2. Уплотнение
По мере заполнения памяти становится все труднее удовлетво-
рять запросы на большие области. Если получен запрос на область,
которая превосходит по длине наибольшую пустую область, то мож-
но действовать тремя возможными способами. Один из них — просто
(а)
(Ь)
Рис. 5.5. Уплотнение памяти,
(а) Память до уплотнения.
(Ь) Память после уплотнения.
ответить на запрос отказом. Другой
состоит в том, чтобы вытеснить какой-
нибудь сегмент, находящийся в дан-
ный момент в памяти, т. е. отобрать
у кого-то память и передать процессу,
пославшему новый запрос. Третья
возможность заключается в том, что-
бы провести перегруппировку памяти
и объединить несколько мелких об-
ластей в единый блок, который был
бы достаточно велик, чтобы удовле-
творить пришедший запрос. Этот по-
следний метод называется уплотнени-
ем (рис. 5.5).
При использовании алгоритма пер-
вой подходящей области в системе со
случайной длиной запрашиваемых
областей уплотнения обычно не тре-
буется, пока память не будет почти
заполнена. Поскольку память так или
иначе, близка к переполнению, затра-
ты на перераспределение большей ее
части обычно не окупаются. Однако
если запросы на память велики, то легко представить себе обсто-
ятельства, когда треть памяти не используется из-за внешней фраг-
ментации (см. рис. 4.3). При таких обстоятельствах уплотнение
приемлемо с экономической точки зрения.
Уплотнение может быть выгодно и тогда, когда процессор не
занят выполнением активных заданий. Время, когда процессор про-
стаивает, можно употребить на уплотнение памяти, чтобы осво-
бодить место для еще одного активного задания. Тогда новое актив-
ное задание поможет обеспечить процессор работой. Если бы про-
цессор не занялся уплотнением, он продолжал бы простаивать. По-
этому можно считать, что в этом случае операция уплотнения ничего
не стоит.
Кнут показал, что, если стратегию первой подходящей области
применять в системе, где количество свободных областей стремится
к некоторому пределу (устойчивому равновесию), то количество за-
нятых областей становится примерно вдвое больше количества не-
занятых. Но размеры незанятых областей постепенно уменьшаются.
Поэтому проблема фрагментации оказывается не столь серьезной,
как можно было ожидать. Дополнительные сведения о динамическом
распределении памяти можно найти в книге Кнута [Кнут, 1968].
5.3.2. Стратегии подкачек
В предыдущем разделе мы рассмотрели проблему размещения
сегментов в памяти. Было отмечено, что размещение страниц —
тривиальная задача, так как размеры всех блоков памяти одинаковы.
Следующая задача, которую нам предстоит рассмотреть — это как
выбирать информацию, которую надо ввести в основную память из
вспомогательной. Сначала мы разберем эту задачу для случая стра-
ничной организации, а затем обобщим для случая сегментации.
Говоря о принятии решения, какие страницы передать из вспо-
могательной памяти в основную, надо рассмотреть два подхода: под-
качку страниц по запросу и опережающую подкачку. Если можно
предсказать поведение программ, т. е. выяснить, какие страницы
потребуются в ближайшем будущем, то, разумеется, опережающая
подкачка страниц сократит число прерываний из-за отсутствия стра-
ницы. Экономия, которую дает исключение одного прерывания,
равна разности между затратами на обслуживание прерывания и за-
тратами на опережающий выбор страницы, которую следует ввести.
Затраты, связанные с переносом новой страницы с барабана не эко-
номятся, так как эту страницу все равно придется ввести с опереже-
нием запроса или по запросу. Если какая-то страница вводится
преждевременно, т. е. подкачивается с опережением, а потом ни разу
не используется, то ненужная работа составит определенные потери.
Туда войдут процессорное время, затраченное на выбор страницы,
время работы канала, затраченное на ввод в оперативную память,
и время, в течение которого введенная страница будет занимать
физическую страницу оперативной памяти. Из сказанного ранее,
очевидно, следует, что потери при преждевременном вводе одной
страницы гораздо больше, чем выигрыш, получаемый при правиль-
ной опережающей подкачке одной страницы. Поэтому, чтобы опере-
жающая подкачка окупалась, вероятность того, что введенные с опе-
режением запросов страницы будут использованы, должна быть
очень большой.
Алгоритм опережения должен обеспечивать уверенность в том,
что информация, которую он вводит, будет использована до того,
как ее вытеснит другая вводимая страница.
К сожалению, трудно предсказать, к каким страницам програм-
ма будет обращаться. Таким образом, в большинстве случаев стра-
тегия подкачки страниц по запросу оказывается выгоднее. Было
показано, что при определенных допущениях относительно стои-
мости соответствующих операций опережающая подкачка страниц
фактически никогда не дает выигрыша по сравнению с подкачкой
по запросу [Ахо и др., 1971]. Бывают все же особые условия, когда
метод опережающей подкачки пригоден. Например, может быть
известно, что каждой программе нужны определенный набор систем-
ных таблиц и начальная группа команд, чтобы приступить к работе.
В этом случае имеет смысл загрузить соответствующие страницы
сразу, не дожидаясь, пока программа запросит их с помощью пре-
рываний [Оппенгеймер и Вайцер, 1968]. Подобные рассуждения
применимы и при сегментно-страничной организации. Когда начи-
нает работать какой-то сегмент, он с очень большой вероятностью
будет обращаться к некоторым своим страницам. Здесь тоже опере-
жающая подкачка страниц может сократить число прерываний. Од-
нако в большинстве случаев стратегия опережения проигрышная,
так как неверные предсказания обходятся гораздо дороже, чем могут
сэкономить правильные.
Страничная организация без аппарата запросов встречается
редко. Сегментация без аппарата запросов — еще реже. Опережаю-
щая подкачка страниц бывает полезна главным образом в тех слу-
чаях, когда известна какая-то логическая связь между страницами.
Но поскольку большинство сегментов уже представляют собой ка-
кие-то содержательные части программы, многие соображения, по
которым можно было бы предсказать порядок обращений к страни-
цам, теряют смысл. Поэтому выборку сегментов из вспомогательной
памяти почти всегда следует организовывать на основе аппарата
запросов. В оставшейся части этой главы мы будем считать, что стра-
ничная организация и сегментация работают на основе аппарата
запросов.
5.3.3. Правила вытеснения страниц
Пусть нужно определенную страницу переместить в оперативную
память. Вопрос в том, куда ее поместить. Если есть незанятая физи-
ческая страница, то не возникает никаких трудностей. Но в боль-
шинстве случаев каждая физическая страница содержит какую-то
математическую страницу, и следует решить, какую страницу надо
вытеснить. Стратегия принятия таких решений называется правилом
вытеснения. Хотя эти правила одинаково применимы к вытеснению
как страниц, так и сегментов, ниже мы будем для единообразия поль-
зоваться терминологией, относящейся к страничной организации.
Правила вытеснения оцениваются с точки зрения того, насколько
хорошо они сокращают ожидаемый объем движения страниц. Идея
в том, чтобы не вытеснять «нужные» страницы. Так, страницы, обра-
щений к которым не ожидается, как правило, больше подходят для
вытеснения, чем те, к которым ожидаются обращения. Выбранная
стратегия, состоящая из одного или нескольких работающих сов-
местно правил, может применяться локально или глобально. Когда
правило замещения применяется локально, память делится на рабо-
чие поля таким образом, что на каждое работающее задание прихо-
дится одно рабочее поле. Избранное правило применяется в преде-
лах каждого рабочего поля вне всякой связи с остальными полями.
При глобальном применении правила вся память рассматривается
как единое целое, т. е. правило применяется ко всей памяти незави-
симо от того, какое задание посылает запрос.
В этом разделе мы рассмотрим некоторые наиболее распростра-
ненные правила вытеснения. Далее в этой главе будет проанализи-
ровано поведение системы в случае применения некоторых из них.
5.3.3.1. Случайный выбор
При этой стратегии страница, которую надлежит убрать, выби-
рается случайным образом. Конечно, это очень легко реализовать,
но, очевидно, что часто вытесняются нужные страницы.
5.3.3.2. «Первым пришел — первым ушел» (FIFO)
В этой стратегии удаляется «самая старая» страница, т. е. та,
которая к моменту принятия решения находится в оперативной па-
мяти дольше всех. Стратегию FIFO можно применять и локально,
в пределах памяти каждого процесса, и глобально, по всем страни-
цам памяти. Ее очень легко реализовать: физические страницы (пусть
их количество равно К) образуют список из К элементов, упорядо-
ченный по номерам страниц; указатель списка показывает самую
новую страницу. Каждый раз, когда нужно ввести какую-то стра-
ницу, содержимое указателя складывается по модулю К с единицей
и страница, на которую указывает полученное значение, удаляется.
Недостаток этой процедуры состоит в том, что она очень неудачно
работает, когда система более или менее плотно загружена, по-
скольку очень часто вытесняются нужные страницы. Ясно, что самая
старая страница не обязательно наименее нужная. Кроме, того, хо-
тя, основываясь на опыте, можно утверждать, что в программах
порядок выборки команд имеет последовательный характер, ссылки
на информацию совершенно непоследовательны. Если бы это было
так, то стратегия FIFO была бы идеальной. Несмотря на то что стра-
тегия FIFO привлекательна с точки зрения простоты реализации,
она существенно ограничивает производительность системы.
5.3.3.3. Стратегия FIFO «с пристрастием» (В/ГО1))2)
Это локальная стратегия. Каждому активному заданию i выделен
набор из n(i) страниц, где, вообще говоря, n(i)=£n(j) при b^j. В пре-
делах каждой группы из n(i) страниц применяется стратегия FIFO.
Через каждые t единиц времени значения n(i) для всех i изменяются,
так что набор какого-то задания может увеличиваться или умень-
шаться. Поэтому в каждый момент времени система покровительст-
вует одному или нескольким заданиям. Меняя значения n(i), мы
распространяем покровительство на различные задания. Значения
параметров п(!) и t выбираются в зависимости от характеристик как
системы, так и заданий.
5.3.3.4. Вытеснение по давности использования (LRU 3))
В этой стратегии удаляется страница, ссылки на которую не
встречались дольше, чем на все другие страницы. Стратегию доволь-
но трудно реализовать. В наиболее распространенной программной
реализации каждой странице ставится в соответствие один бит. Си-
стема ведет таблицу, в которой каждой странице памяти соответст-
вует запись, содержащая число промежутков времени с момента
последнего обращения к странице. Когда происходит обращение
к странице, в соответствующий бит устанавливается единица. Через
определенные промежутки времени все биты проверяются, чтобы
узнать, к каким страницам за последний промежуток не было обра-
щений. Номера этих страниц затем отражаются в таблице; значения
связанных с каждой такой страницей счетчиков промежутков без
обращений увеличиваются на единицу. При вводе новой страницы
система справляется по таблице: вытесняется та страница, к которой
не было обращений в течение наибольшего числа промежутков вре-
мени.
Опыт показывает, что в большинстве случаев стратегия LRU
работает хорошо. Ее основной недостаток в том, что ее реализация
дорого стоит. Но с помощью аппаратного оборудования эту стра-
тегию можно сделать более приемлемой с экономической точки зре-
ния. Например, можно реализовать аппаратно установку бита об-
ращения при каждом обращении к странице. При многоуровневой
памяти вытеснение страниц обычно происходит по правилу LRU,
реализованному аппаратно. Правило LRU — это наиболее распрост-
раненная стратегия, используемая для вытеснения страниц.
J) От «biased FIFO».— Прим, перев.
2) См. Биледи и Кюнер [1969].
3) От «least recently used».— Прим, перев.
5.3.3.5. Предписанные приоритеты
Этот метод предусматривает, что программист или компилятор
вставляет в программу специальные указания для системы, каким
страницам следует на ближайшее будущее присвоить высокий при-
оритет. Если язык программирования обладает высокой степенью
структурности, то компилятор имеет возможность проследить ход
обращений, что помогло бы системе при принятии решений о вытес-
нении страниц. Пользуясь предварительно заданными приоритетами,
система может судить о том, к каким страницам в ближайшем буду-
щем обращения наименее вероятны.
5.3.3.6. Приоритеты, задаваемые системой
Подобным же образом алгоритм вытеснения может быть основан
и на тех приоритетах, которые присваиваются всем заданиям самой
системой с целью планирования. Задания, находящиеся в данный
момент в системе, образуют очередь в соответствии с приоритетами.
Когда происходит прерывание, в очереди отыскивается задание
с самым низким приоритетом среди тех, которые занимают страницы
оперативной памяти. Если таких заданий несколько, то выбор одного
из них может производиться и по дополнительному правилу, на-
пример по длительности пребывания в системе. Страницу, которую
следует вытеснить, система выбирает из страниц выбранного зада-
ния, пользуясь каким-либо правилом, например LRU. Если у про-
граммы, в которой произошло прерывание, самый низкий приоритет,
то новая страница должна вытеснить одну из страниц своей же про-
граммы. Если окажется выброшенной последняя страница какого-то
задания, то ему придется ждать до тех пор, пока какое-нибудь другое
задание не окончится и не освободит несколько физических страниц.
Недостаток этого алгоритма состоит в том, что задания с наивыс-
шим приоритетом часто накапливают много страниц, которые уже
больше не понадобятся. Эти бесполезные страницы остаются в памя-
ти до тех пор, пока программа не окончит работу, так как никакой
другой программе не разрешается отбирать у нее физические стра-
ницы.
5.3.3.7. Оптимальное вытеснение
Наконец, существует алгоритм, называемый ОРТ. Он был пред-
ложен Биледи [1966], а его оптимальность была доказана Мэттсоном
и др. [1970]. При его применении отношение числа прерываний из-за
отсутствия страницы к числу обращений к памяти минимально.
Алгоритм ОРТ убирает ту страницу, обращения к которой не про-
изойдет дольше всего. Хотя этот алгоритм оптимален, у него есть
один весьма серьезный недостаток: его невозможно реализовать,
поскольку в любой заданный момент невозможно иметь полные све-
дения о будущих обращениях к памяти. Темне менее алгоритм ОРТ
бывает полезен в качестве эталона при оценке других, реализуемых
алгоритмов.
5.3.3.8. Смешанные методы
Описанные методы определяются точно и изящно, но существует
еще много смешанных и основанных на здравом смысле правил, ко-
торые работают так же хорошо. Например, в операционной системе
с разделением времени Spectra 70/46 (RCA Corp.) для вытеснения
страницы предлагается на выбор список возможностей, упорядочен-
ный по убыванию степени их желательности [Оппенгеймер и Вайцер,
1968]:
1) принадлежащая неактивной в данный момент задаче страница,
использованная только для чтения;
2) принадлежащая неактивной задаче страница, использованная
для записи;
3) страница управляющей программы, к которой не было обра-
щений последние полсекунды;
4) страница активной задачи, ожидающей ввода-вывода;
5) страница какой-то другой активной задачи.
Система ведет списки страниц для каждой подгруппы. Когда
необходимо вытеснить какую-то страницу, она выбирается из наи-
более желательного непустого списка.
Вообще при проектировании системы выбор стратегии вытесне-
ния представляет собой сложную задачу. Некоторые методы, о ко-
торых известно, что они хорошо работают, например метод LRU,
трудно реализовать без помощи аппаратного оборудования. А мно-
гие более простые алгоритмы очень часто вытесняют нужные стра-
ницы. В следующем разделе мы рассмотрим несколько аналитиче-
ских методов, применяемых для сравнения стратегий вытеснения,
которые должны помочь проектировщику сделать разумный выбор.
5.4. Анализ типов страничной организации
Выше были изложены стратегии подкачки и вытеснения страниц.
Для того чтобы сделать разумный выбор между этими взаимоиск-
лючающими схемами, нужно хорошо понимать поведение программ
и систем при страничной организации памяти. Одна из попыток
смоделировать их поведение — идея рабочего множества [Деннинг,
1968].
5.4.1. Модель рабочего множества и локализованность
Программа, работающая на машине со страничной организацией,
обычно не держит в оперативной памяти все свои страницы одно-
временно. Если в памяти присутствуют те страницы, к которым она
обращается часто, то будет не так много вызовов страниц из вспомо-
гательной памяти, т. е. движение страниц будет слабым. Говоря
нестрого, рабочее множество процесса — это такое множество стра-
ниц, которое нужно держать в оперативной памяти, чтобы в течение
достаточно большого промежутка процессорного времени не про-
изошло прерывания из-за отсутствия страницы [Деннинг, 1968;
Деннинг и Шварц, 1972]. Какие именно страницы должны быть в
оперативной памяти, система обязана определить сама на основании
наблюдений над распределением обращений.
Рабочее множество W(t,T) процесса для момента t есть, по опре-
делению, совокупность всех страниц, к которым процесс обращается
на протяжении интервала процессорного времени (t—T,t), где про-
цессорное время — это время, в течение которого процессор был
предоставлен процессу. Таким образом, рабочее множество — это
в точности те страницы, к которым происходили обращения за по-
следние Т секунд процессорного времени.
Пусть е — доля команд процессора, приводящих к прерываниям
из-за отсутствия страницы, ар — доля страниц процесса, находящих-
ся в памяти. Если считать, что распределение ссылок на адреса в
процессе случайное (т. е. любая ссылка может быть с равной вероят-
ностью обращена к любой странице), то е=1 — р. Однако известно,
что обращения программ к адресам памяти распределяются не слу-
чайно. Обращения имеют тенденцию сгущаться вокруг некоего под-
множества всех страниц программы,* а именно вокруг подмножества,
содержащего собственно команды и данные, с которыми в данный
момент работает программа. Это свойство программ, состоящее в том,
что адреса обращений имеют тенденцию сгущаться, называется лока-
лизованноспгью. Если в памяти присутствует подходящее подмно-
жество страниц программы (например, рабочее множество програм-
мы), то ввиду локализованное™ программы передача дополнитель-
ных страниц в память вряд ли существенно улучшит коэффициент е
прерываний из-за отсутствия страницы.
На рис. 5.6 показана зависимость коэффициента прерываний от
характера обращений для случайного и сгущающегося распределе-
ний. Заметим, что для кривой LOG, после того как примерно треть
всех страниц процесса допускается в память, увеличение р не дает
заметного уменьшения е.
При построении этого графика было сделано существенное до-
пущение. Предполагалось, что при каждом значении р в памяти
находятся р самых подходящих страниц, т. е. те р страниц, обраще-
ния к которым наиболее часты. К тому же предполагается, что по
р {Доля страниц, находящихся в памяти}
Рис. 5.6. Зависимость коэффициента прерываний от характера распределения
ссылок. (RAND — кривая для случайного распределения ссылок; LOC — кривая
для программ с локально сгущающимся распределением ссылок.)
мере выполнения программы система обслуживает прерывания из-за
отсутствия страниц таким образом, что всегда в памяти присутству-
ют те страницы, которые чаще всего используются. Степень соответ-
ствия этих предположений действительности, очевидно, зависит от
применяемой стратегии вытеснения. Например, метод ОРТ удовлет-
воряет этим допущениям, а метод LRU — нет.
Деннинг предложил основанное на идее рабочего множества
правило вытеснения, с помощью которого можно оптимизировать
кривую LOC. Однако есть и другие методы повышения произво-
дительности страничной системы. При тщательно продуманном рас-
положении на страницах программы и данных можно добиться сгу-
щения обращений к страницам, увеличив таким образом локализо-
ванность процесса. Некоторые из этих методов мы рассмотрим в
разд. 5.4.3.
5.4.2. Аномалии в алгоритмах страничной организации
5.4.2.1. «Толкотня» в памяти
Когда замена страниц в оперативной памяти или рабочем прост-
ранстве, выделенном в памяти для какой-то задачи, чересчур ин-
тенсивна, усилившееся движение страниц может привести к опа-
сному вырождению деятельности системы. Это явление называется
толкотня» х) в памяти.
Если действует принцип локального вытеснения, когда правило
вытеснения применяется в пределах рабочего пространства каждого
задания и какому-то заданию выделено недостаточно физических
страниц, то любое прерывание из-за отсутствия страницы может
привести к вынужденному вытеснению нужной страницы. Значитель-
ная часть ссылок на адреса порождает прерывания, доводя движение
страниц до угрожающе высокого уровня. Подобные же результаты
получаются и при глобальном вытеснении. Если потребность в опе-
ративной памяти слишком велика, то любое обращение к отсутст-
вующей странице вынуждает систему убирать нужную страницу,
возможно принадлежащую другому заданию. Движение страниц
усиливается, а работа системы соответственно вырождается. В ре-
зультате большая часть времени расходуется на обслуживание за-
просов на отсутствующие страницы; в то время как машина работает
в полную силу, полезная деятельность стоит на мертвой точке.
Следует помнить, что, хотя виртуальная память обычно дает
отличные результаты, если около трети каждого активного задания
помещается в оперативной памяти, но настоящую оперативную па-
^мять ничем заменить невозможно. Большим программам при любых
' системах управления памятью нужно много оперативной памяти.
5.4.2.2. Аномалия Биледи
При определении эффективности конкретной страничной стра-
тегии важно иметь какое-то объективное средство для оценки алго-
ритма. Слишком уж часто здравый смысл и интуиция вводят нас
в заблуждение. Например, можно предположить, что по мере увели-
чения числа физических страниц, выделенных программе, количество
прерываний из-за отсутствия страниц падает. Хотя в среднем это,
конечно, верно, бывают случаи, когда выходит все наоборот [Биледи
и др., 1969]. Рассмотрим программу, занимающую пять страниц,
именами которых служат номера от единицы до пяти. Наблюдения
показали, что при стратегии FIFO пятистраничная программа
с распределением обращений 1-2-3-4-1-2-5-1-2-3-4-5, имея четыре фи-
зические страницы, порождает десять прерываний из-за отсутствия
страницы, а имея три физические страницы,— только девять пре-
рываний!
Хотя этот пример кажется исключительным при алгоритмах вы-
теснения типа FIFO, он не вполне искусственный. Были обнаружены
реальные программы, которые ведут себя подобным образом. Этот
г) В оригинале «thrashing». В литературе употребяются также термины «трэ-
шинг» и «перебарабанивание».— Прим. ред.
пример служит предостережением о том, что, не проанализировав
поведение системы тщательным образом, проектировщик может по-
лучить удивительные и часто нежелательные результаты.
5.4.3. Влияние страничной организации
на структуру программ
Выше мы отмечали, что если обращения к станицам в программе
достаточно локализованы, то для того, чтобы обеспечить невысокий
коэффициент прерываний, требуется относительно мало физических
страниц. За счет аккуратной организации программы можно добить-
ся значительно большей локализации ссылок.
5.4.3.1. Распределение программы по страницам
Способ разбиения программы на страницы может существенным
образом отразиться на степени локализованное™ ссылок. Были
поставлены эксперименты, в которых изменение распределения про-
граммных модулей привело к драматическим переменам в процессе
замены страниц [Комо, 1967]. Известно, что стиль программирования
также оказывает влияние на производительность конкретной систе-
мы распределения по страницам. В недавно опубликованном иссле-
довании из области структурного программирования предлагается
унифицировать стиль программирования [Вайнберг, 1971]. Четкое
определение хорошего стиля программирования сделает возможньш
построение компиляторов, которые распределяли бы страницы более
эффективно, так как характер распределения обращений будет из-
вестен уже во время трансляции. Но разработка эффективных ав-
томатических методов распределения программ по страницам пока
только начинается.
5.4.3.2. Страничная оптимизация системы ATLAS
Система ATLAS, которая представляет собой один из ранних опы-
тов страничной системы с вызовом страниц по запросу, стремится
каждый цикл программы разместить в пределах одной страницы.
Цель этой стратегии состоит в том, чтобы обращаться к той же самой
странице (или страницам) снова и снова. Это, по существу, попытка
усилить локализованность обращений с помощью разумного распре-
деления программы по страницам. Этот способ весьма эффективен
для циклов, но не помогает при более случайном характере распре-
деления ссылок. К тому же его реализация может очень дорого обой-
тись.
5.4.3.3. Оптимизация работы с матрицами
В вычислительных задачах, работающих с большими матрицами,
обращения к памяти слабо локализованы; это может существенно
снизить производительность страничной системы. Мак-Келлар и
Коффман [1969] показали, что при хорошо продуманном порядке
следования матричных операций можно избежать огромного коли-
чества ссылок на отсутствующие страницы. Однако индексация эле-
ментов массивов усложняется, так что вычисление адреса обходится
несколько дороже. Тем не менее выигрыш, полученный от сокраще-
ния числа обращений к отсутствующим страницам, оказывается боль-
ше, чем дополнительные затраты на вычисление индексов элементов.
Кроме того, при решении больших систем уравнений последователь-
ным исключением переменных с ограниченным выбором опорных
переменных (т. е. по методу Гаусса) можно значительно улучшить
коэффициент прерываний для больших матриц, если хранить их
в памяти в виде группы подматриц.
Такой анализ поведения программ полезен при создании ком-
пиляторов для систем со страничной организацией. Применяя по-
добные методы, можно создавать трансляторы с языков и пакеты
подпрограмм, которые оптимизировали бы программы применитель-
но к условиям страничной организации.
5.4.4. Проблемы проектирования систем
со страничной организацией
У вычислительных систем со страничной организацией памяти
имеется много свободных параметров, подбирая которые можно по-
лучать хорошие проекты систем. Назовем некоторые из них. Имеется
выбор различных правил вытеснения, размеров оперативной памя-
ти, способов разбиения заданий, стратегий планирования, размеров
страниц. В этом разделе мы рассмотрим несколько аналитических
результатов, относящихся к конструктивным решениям систем.
Наша цель — только провести выборочный обзор статей, посвящен-
ных анализу страничных систем.
5.4.4./. Сравнение правил вытеснения
В числе правил вытеснения, изложенных в разд. 5.3.3, имеется
алгоритм ОРТ [Биледи, 1966; Мэттсон и др., 1970], о котором извест-
но, что он оптимальный. Хотя реализовать этот алгоритм на насто-
ящей системе нельзя, его можно смоделировать. Моделирование
правила вытеснения обычно включает в себя запуск нескольких
эталонных программ и регистрацию каждого обращения к новой
странице во время их работы. Полученную последовательность об-
ращений к страницам можно затем использовать как входные дан-
ные для моделирующей программы, которая определяет поведение
коэффициента прерываний из-за отсутствия страниц при различных
стратегиях вытеснения и размерах памяти. Заметим, что при этом
Рис. 5.7. Сравнение стратегий вытеснения LRU и ОРТ*
Рис. 5.8. Зависимость длины промежутка времени между прерываниями из-за
отсутствия страницы в памяти от размера рабочего пространства. (Т — время меж-
ду прерываниями, N — число страниц в памяти.)
можно реализовать алгоритм ОРТ, так как известны все будущие об-
ращения к памяти. Тем самым мы обеспечиваем основу для сравне-
нения с другими правилами.
Чтобы получить протоколы последовательностей ссылок, Коф-
фман и Вариан [1968] выбрали четыре эталонные программы: ком-
пиляторы с языков SNOBOL и WATFOR, программу преобразова-
ний Фурье и программу, решающую дифференциальные уравнения.
Результаты проверки, полученные для этих программ при страте-
гиях LRU и ОРТ, обобщены на рис. 5.7. Было обнаружено, что во
всех случаях разница между стратегиями LRU и ОРТ находится
в пределах 30—40 процентов. Кроме увеличения числа запросов
отсутствующих страниц, которое и ожидалось при уменьшении коли-
чества выделенных физических страниц, Коффман и Вариан обна-
ружили, что увеличение числа страниц, находящихся в памяти,
более выгодно, чем увеличение размера страниц (см. также разд:
5.4.4.2).
Биледи и Кюнер [1969] сравнили коэффициенты прерываний при
стратегиях.FIFO и BIFO. Зависимость длины промежутка времени
между прерываниями из-за отсутствия страницы для программ с
умеренно локализованными обращениями к памяти от количества
выделенных программе физических страниц изображена на рис. 5.8.
Большинство схем страничной организации выделяет каждому за-
данию фиксированное число страниц, допустим А страниц. Приме-
нив математическое моделирование, Биледи и Кюнер обнаружили,
что среднюю продолжительность промежутка между прерываниями
можно увеличить, если половину всего времени задание будет ра-
ботать с А—k физическими страницами, а другую половину — с A -}-k
физическими страницами, где k — небольшая целая постоянная.
Эксперименты, поставленные со стратегией BIFO с применением
этой схемы «возрастающего пристрастия», показали, что пра-
вило BIFO дает увеличение промежутка между прерываниями
на 10—15 процентов по сравнению с «беспристрастным» прави-
лом FIFO.
В предыдущих примерах для сравнения методов вытеснения ис-
пользовались моделирование и анализ с помощью математических
методов. Однако многие системы (например, Spectra 70/46) приме-
няют стратегии специализированного назначения, которые с тру-
дом поддаются анализу. К тому же у каждой системы свои особен-
ности, и результаты моделирования трудно обобщать. Поэтому не
удивительно, что, несмотря на существование большого числа ра-
бот по стратегиям вытеснения, между проектировщиками систем
нет подлинного единодушия в вопросе о том, какая стратегия «самая
подходящая» для реализации.
5А.4.2. Определение размера страниц
Имеется несколько факторов, влияющих на выбор оптимального
размера страниц. Чтобы уменьшить внутреннюю фрагментацию, надо
иметь страницы небольшого размера. Но с уменьшением размера
страниц увеличивается число страниц, необходимых для размеще-
ния большой программы. Следовательно, таблица страниц каждой
программы удлиняется. Если учитывать только внутреннюю фраг-
ментацию и длину таблицы страниц, то для программ средней вели-
чины размер страниц должен быть около 45 слов [Деннинг, 1970].
К сожалению, при небольшом размере страниц усиливается их
движение, что существенно усложняет дело. Поскольку при выбор-
ке страниц из вспомогательной памяти решающее значение имеет
время поиска, увеличение числа подкачек существенно снижает
производительность системы. Следовательно, нужно ослабить дви-
жение страниц, а для этого требуются относительно большие стра-
ницы. Чтобы уравновесить фрагментацию и длину таблицы страниц
с движением страниц, размер страницы обычно выбирают в пределах
от 256 до 1024 слов.
5.4.4.3. Другие результаты
Было сформулировано и решено много интересных задач, свя-
занных со страничной организацией памяти. Коффман и Ренделл
[1971] показали, что для определенного класса алгоритмов вытесне-
ния можно предсказать, каким будет коэффициент прерываний из-за
отсутствия страниц, если в систему добавить дополнительную па-
мять. Все, что нужно знать для такого предсказания,—это протокол
вытеснений страниц, который легко получить, запустив эталонные
программы в системе до расширения памяти. Таким образом можно
до фактической закупки дополнительной памяти определить, на-
сколько улучшится режим работы системы.
Деннинг [1968] предложил модель, в которой запросы на память
и на процессор могут быть уравновешены. Путем прогнозирования
запросов как на процессор, так и на память с помощью матема-
тических функций можно подбирать задания, которые поддерживали
бы равновесие между этими двумя ресурсами. Хотя этот подход дей-
ствительно помогает максимально использовать ресурсы, он может
идти вразрез с требованием уменьшить время ожидания для отдель-
ных пользователей.
Биледи и Кюнер [1969] изучили влияние ограничения выделяе-
мого большим задачам пространства на работу системы. Получен-
ные ими результаты показывают, что стратегия распределения,
ограничивающая долю памяти, выделяемой каждому процессу, в
действительности увеличивает загрузку системы, так как при этом
другим процессам в течение длительного времени не разрешается
распространяться на эту долю памяти. Они также пришли к заклю-
чению, что если один процесс требует особенно много памяти, то
его требование стоит удовлетворить, чтобы этот процесс как можно
скорее покинул систему.
Коффман и Райэн [1972] исследовали фиксированные и динами-
чески меняющиеся размеры частей памяти, выделяемых отдельным
процессам. Полученные ими результаты показывают, что для рабо-
чих множеств, размер которых меняется мало, по-видимому, прием-
лемы фиксированные доли памяти. Коффман и Райэн получили и
количественную оценку экономии, которую дает динамическое из-
менение доли памяти для рабочих множеств, размер которых сильно
меняется с течением времени.
Райс и ван Дам [1971] исследовали проблему выбора параметров
страничной организации для конкретного случая системы, предназ-
наченной для редактирования текстов. В частности, они рассмотрели
размер страниц, правила вытеснения, разбиение информации на
страницы и размер рабочего пространства. Проведен и сравнитель-
ный анализ страничной организации и сегментации. Авторы при-
ходят к выводу, что для редактирования текстов, по-видимому,
подходят оба метода и что при выборе подхода решающим фактором,
вероятно, должна быть простота реализации.
Имеется множество материалов по анализу страничных систем.
Отчасти это связано с возрастающим значением виртуальной па-
мяти и с тем, что проблемы страничной организации можно легко
сформулировать. Читателя, который захочет продолжить ознаком-
ление с такими аналитическими методами, мы отсылаем к аннотиро-
ванному библиографическому указателю.
5.5. Заключительные
замечания
Хотя в этой главе упор был сделан на страничную организацию
в системах виртуальной памяти, имеются и очень удачные системы
с чистой сегментацией (особенно системы фирмы Burroughs). Но
вообще передачу сегментов переменной величины реализовать труд-
но. Все же существование естественных границ между программами
и данными, разбивающих задание на сегменты переменной длины,
делает этот подход интуитивно привлекательным. Очевидный комп-
ромисс, воплощенный в сегментно-страничной системе (см. разд.
4.8), использует лучшие свойства обеих стратегий. Однако он воспри-
нял и многие их недостатки. Реализация этого подхода в системе
MULTICS показала, что он приемлем. Но остается открытым вопрос,
действительно ли полученные дополнительные удобства оправды-
вают применение такой сложной системы адресации.
Задания
5.1. Существует ряд отклонений от принципа строгой иерархии памя-
ти, рассмотренного в разд. 5.2.1. Например, информация может быть
передана с магнитной ленты на диск только через оперативную па-
мять. Другим примером служат некоторые машины фирмы CDC, в ко-
торых информация может передаваться с диска в медленную память
на сердечниках только через быструю память. Можете ли вы объяс-
нить эти отклонения?
5.2. Опишите в общих чертах вычислительную систему, в которой
один процессор занимается управлением памятью, а другой выпол-
няет только вычисления для заданий пользователей.
5.3. В большинстве теоретических моделей виртуальной памяти
рассматривается подкачка страниц по запросу. С другой стороны,
во многих реальных системах в момент начала работы задания вы-
полняется опережающая подкачка страниц в той или иной форме.
Почему имеет место эго явное расхождение?
5.4. Попытайтесь дать формальное определение программы с лока-
лизованными обращениями к памяти. Как бы вы определили свой-
ство локализованности для информационной структуры, используе-
мой одновременно многими процессами? В одинаковой ли степени
этим свойством обладают программные модули и модули данных?
Дайте обоснованный ответ.
5.5. Укажите некоторые свойства языков программирования, кото-
рые могут привести к слабой локализованности ссылок в программе.
Предложите набор неформальных правил программирования, ко-
торые, если их придерживаться, улучшат локализованность ссы-
лок в составляемых программах [Вайнберг, 1971].
5.6. Предположим, что процессы обслуживаются в порядке убывания
приоритетов. Опишите алгоритм вытеснения страниц, благоприятст-
вующий заданиям, которые близки к получению процессора. Поче-
му этот алгоритм не равносилен тому, чтобы всегда вытеснять стра-
ницы задания с наименьшим приоритетом?
5.7. Алгоритм вытеснения страниц FIFO — один из самых простых
и недорогих для реализации. Однако вытеснение страниц по методу
FIFO может привести к «толкотне», особенно если применять его
глобально, ко всем страницам памяти. Предложите простое видо-
изменение реализации, которое позволило бы избежать «толкотни»,
лишь слегка изменив правило FIFO. Можете ли вы оценить эффек-
тивность вашего алгоритма по сравнению с правилами LRU и
ОРТ.
5.8. Рассмотрите некоторые из алгоритмов вытеснения страниц, из-
ложенных в этой главе. Охарактеризуйте программы, которые лучше
всего работают при каждом из них.
5.9. То, каким образом компилятор распределяет скомпилированную
программу по страницам, может оказать значительное влияние на
поведение прерываний из-за отсутствия страниц (см., например,
[Мак-Келлар и Коффман, 1969]). «Умный» компилятор может уметь
предсказывать характер распределения ссылок на основании исход-
ного текста. Можете ли вы выделить несколько хороших правил для
отдельных ситуаций, которым должен следовать компилятор при
распределении объектной программы по страницам? Как бы вы могли
убедиться, что эти правила эффективны?
5.10. Приведите пример программы, рабочее множество которой
очень сильно меняется с течением времени. Какие алгоритмы вы-
теснения особенно плохи для такой программы? Какие особенно
хороши?
5.11. Предположим, что операционная система управляет свободной
памятью при помощи системы расщепления, как описано в разд.
5.3.1.1. Если задание в системе нечаянно (или по злому умыслу)
возвращает одну и ту же область памяти дважды, это в конце концов
расстроит работу системы. Перестройте систему расщепления так,
чтобы она стала совершенно защищенной от некомпетентного
вмешательства. (Считайте, что машина не имеет физических
средств защиты памяти.) Сравните свою защищенную систему рас-
щепления с алгоритмом, выбирающим первую подходящую об-
ласть.
5.12. Следующий алгоритм вытеснения страниц (здесь он слегка
упрощен) был предложен для машины ATLAS [Килберн и др.,
1962].
Для каждой (присутствующей и не присутствующей в памяти)
страницы система записывает t — время, прошедшее с тех пор, когда
к этой странице обращались в последний раз, и Т — промежуток
времени между предыдущими двумя ссылками на эту страницу.
Время измеряется количеством выполненных команд. Когда нужно
вытеснить страницу, система выбирает ту, для которой
1) f^T+1
или, если таковых нет,
2) Т—t максимально и
В чем смысл применения такого алгоритма? Насколько он чув-
ствителен к стилю программирования? Укажите причины, по ко-
торым этот алгоритм на практике работает не так хорошо, как пра-
вило LRU.
5.13. В системе с виртуальной памятью оперативная память должна
распределяться эффективно. Это значит, что недопустимо предо-
ставлять программе больше физических страниц памяти, чем ей на
самом деле нужно. Как бы вы организовали выявление таких ситу-
аций, совершенно противоположных «толкотне»? Допустим, что
программам выделяются индувидуальные области оперативной па-
мяти и вытеснение страниц выполняется локально, внутри индиви-
дуальной области. Какие меры потребуются в этом случае, чтобы
убедиться, что каждая программа получает не больше страниц, чем
занимает ее рабочее множество?
5.14. Опишите систему оплаты использования оперативной памяти
в условиях страничной организации. Должен ли пользователь пла-
тить за такие внутрисистемные трудности, как характер распределе-
ния запросов страниц и большой размер рабочего множества?
Часть II
ТЕХНОЛОГИЯ
Материал, изложенный в части I этой книги, имел концептуаль-
ный характер. Операционная система рассматривалась как набор
процессов, взаимодействующих между собой при использовании ос-
новных ресурсов системы. Введенные в части I понятия, такие, как
процессы и управление памятью, являются основными и вполне
наглядными.
Кроме того, операционные системы имеют некоторые аспекты,
которые сложились исторически, и много новых аспектов, которые
еще не до конца поняты. Системы управления файлами дают нам
пример первых, а проблемы проектирования — вторых. Можно при-
нять точку зрения пуриста и обойти все эти вопросы. Ценность
обсуждения этих вопросов состоит в том, что оно позволяет подверг-
нуть материал более тщательному исследованию. Возможно, в буду-
щем будет открыто несколько новых принципов, которые дадут воз-
можность унифицировать предмет исследования и выделить неболь-
шое число основных идей. Вопросы защиты находятся, по-видимому,
именно в таком положении. Материал, охватываемый последними
пятью главами этой книги, может показаться случайно подобранным
и плохо скомпонованным. Наша неспособность хорошо его описать
не должна помешать, однако, признанию его важности. Трудно
разъяснить идеи, которые в данный момент еще развиваются. С дру-
гой стороны, было бы неправильно и игнорировать их, так как они
непосредственно влияют на самую суть того, что принято называть
операционными системами.
Глава 6
ВВОД-ВЫВОД И ФАЙЛЫ
6.1. Введение
Аппарат файлов предоставляет пользователям еще один нагляд-
ны"’ способ работы с именами и организации перемещения данных.
Файл — это физическое представление информации о совокупности
объектов. Файл обычно состоит из более мелких единиц, называемых
записями, каждая из которых содержит информацию о конкретном
объекте. Свойства объекта кодируются значениями отдельных полей
записи. В качестве примера рассмотрим файл личного состава. Для
каждого работника в нем имеется одна запись, которая содержит
различные сведения. Поля внутри каждой записи могут быть сле-
дующими: фамилия, адрес, семейное положение, число детей, назва-
ние отдела, фамилия начальника, история трудовой деятельности,
оклад и т. д.
Система управления файлами — это часть операционной системы,
которая реализует работу с файлами. В идеале такая система должна
обеспечивать следующие семь свойств:
1) способность эффективного распределения вспомогательной
памяти;
2) гибкость и многосторонность доступа к данным;
3) возможно большую маскировку внутреннего механизма ре-
ализации от пользователя;
4) независимость от машины и устройств в максимально дости-
жимой степени;
5) способность организации совместного использования общих
файлов (разделения файлов);
6) безопасность и целостность информации, хранимой в файлах;
7) эффективность реализации команд работы с файлами.
Системы управления файлами выполняют две существенно раз-
личные функции. Во-первых, они должны организовать эффектив-
ную работу с данными, хранящимися на различных устройствах
памяти. Во-вторых, системы управления файлами должны предо-
ставить пользователю возможность создавать собственное простран-
ство имен, а также возможность доступа для запоминания или выбор-
ки данных в нем. К сожалению, физические и логические свойства
таких систем иногда смешивались. Это обстоятельство препятство-
вало развитию стройных концепций систем управления файлами.
В этой главе обсуждаются проблемы организации данных во вспо-
могательной памяти, причем для удобства понимания указанные
проблемы определенным образом сгруппированы.
Файлы обычно хранятся на периферийных устройствах, таких,
как дисководы и лентопротяжные устройства. Первая проблема, ко-
торую должна решать система управления файлами, заключается в
эффективном распределении памяти на этих устройствах. Обычно
физическое пространство на периферийных устройствах распреде-
ляется блоками, которые могут быть фиксированной или переменной
длины. В случае страничной системы важно, чтобы размер блока
был определенным образом связан с размером страниц во избежание
неоправданного дробления (фрагментации). Размер блока может вы-
бираться в зависимости (или независимо) от размера записей
в файле.
Каждый файл фактически представляет собой совокупность бло-
ков. Блоки могут быть связаны друг с другом, образуя связные спис-
ки; каждый блок имеет дополнительное место для указателя на сле-
дующий блок в списке. Альтернативой связного списка является
таблица, называемая отображением памяти. Для каждого блока
в отображении памяти имеется информация, описывающая положе-
ние блока в файле. Этот второй метод предпочтительнее, поскольку
он позволяет производить некоторые манипуляции над блоками
без фактического обращения к ним. (Так как обращение к диску
в тысячи раз медленнее обращения к оперативной памяти, отслежи-
вание указателей на диске обходится недопустимо дорого.)
Когда система инициируется, вся доступная память находится
в свободном пуле, т. е. в совокупности блоков, не отведенных еще
никакому файлу. По мере создания и расширения файлов блоки
удаляются из свободного пула и присоединяются к различным фай-
лам. Если файл сокращается или уничтожается, его блоки возвра-
щаются в свободный пул. Стратегии распределения оперативной па-
мяти обсуждались в гл. 5. Здесь применяется аналогичный подход.
Вторая главная проблема, которую должна решать система уп-
равления файлами,— это проблема именования. Пользователи хо-
тят создавать свои собственные пространства имен. Даже когда поль-
зователи работают с общими файлами (т. е. разделяют файлы), они
предпочитают называть эти файлы своими собственными индивиду-
альными мнемоническими именами. В такой ситуации одно имя мо-
жет относиться к различным файлам и различные имена — к одному
файлу. Конфликты наименований должны разрешаться контек-
стом, в котором используется данное имя.
Файлы фактически являются именованными сегментами памяти
[Органик, 1972]. Имя файла, используемое в определенном контек-
сте, определяет функцию отображения адресов в объекты внутри
файла. Для задания структуры в пространстве имен файлы дают
пользователю больше возможностей, чем просто именованные сег-
менты памяти. Записи представляют собой элементы пространства
имен, и ссылки на них могут осуществляться по различным прави-
лам. Другими словами, пространство имен имеет структуру благода-
ря связи между именами. Например, пользователь может представ-
лять записи в файле в последовательном порядке, в виде дерева или
в любом другом порядке, который больше подходит для решения
его проблемы. Системы управления файлами распространяют также
отношения «имя — адрес», описанные в гл. 4 и 5, на другие устрой-
ства, отличные от основной пары «оперативная память — барабан
со страничной организацией». К сожалению, системы управления
файлами исторически возникли раньше хорошо разработанной тео-
рии управления памятью, и поэтому они редко описываются с ис-
пользованием терминологии сегментации и преобразования адресов,
данной в гл. 4.
Регистрируя имена в данном контексте, система управления
файлами оформляет соответствующие записи в справочниках.
Пользователь обращается к конкретному файлу по символическому
имени. Для каждого символического имени из данного контекста
в справочнике существует запись, с помощью которой по символи-
ческому имени можно определить фактическое расположение файла.
Это может быть осуществлено поиском более чем на одном уровне
справочника. Кроме того, справочник содержит информацию, отно-
сящуюся к использованию файла. Например, запись справочника
для одного файла может содержать следующую информацию:
1) символическое имя, которое пользователь связывает с файлом;
2) фактическое местоположение файла;
3) уникальный идентификатор файла, одинаковый для всех поль-
зователей данного файла;
4) тип доступа, разрешенный пользователям;
5) дата последнего использования файла и
6) частота использования.
Рассмотрим в качестве примера файл личного состава, который
совместно используется многими пользователями. Допустим, что
какой-то пользователь желает получить доступ к определенной
записи в файле. Пользователь может определить запись либо по ее
положению внутри файла (например, седьмая запись), либо по не-
которым значениям полей записи, которые единственным образом
определяют запись (например, фамилия и регистрационный номер
системы социального обеспечения). (Ссылка по положению в файле
делает программу сильно зависимой от структуры файла и затруд-
няет некоторые виды разделения файла.)
Чтобы выполнить запрос, система управления файлами должна
определить местоположение файла с заданным именем. Имя файла,
указанное пользователем в данном контексте, служит для поиска
по справочнику пользователя уникального идентификатора файла.
Физический носитель, на котором хранится информация, такой, как
бобина магнитной ленты или пакет дисков, называется томом. После
получения уникального идентификатора система управления фай-
лами пытается найти местоположение определенного тома (томов),
связанного сданным идентификатором. Если том (тома), на котором
хранится файл, не установлен, система управления файлами должна
выдать оператору запрос на установку данного тома на свободное
устройство. Когда это будет сделано, система может осуществить
доступ к файлу. Положение требуемой записи (записей) может
быть задано либо явно, в виде адреса, либо косвенно, например через
вычисление по значениям полей, либо указанием способа поиска,
основанным на известной организации файла. После этого система
управления файлами должна сгенерировать соответствующие
команды для аппаратуры ввода-вывода, которые осуществляют
перепись требуемой записи (записей) файла между оперативной
памятью и периферийными устройствами, хранящими файл.
Если требуется больше одной записи, иногда необходима буфери-
зация.
Из предыдущего обсуждения должно быть ясно, что система
управления файлами должна выполнять много различных операций,
даже обслуживая один-единственный запрос. Некоторые операции,
выполняемые системой, являются логическими по своей природе,
например установление уникального имени файла по локальному
имени, указанному пользователем. Другие операции очень близки
к аппаратным командам, например обмен блоков информации между
оперативной памятью и конкретным устройством. Эти различные
функции системы управления файлами могут быть описаны последо-
вательностью уровней программного обеспечения [Мэдник и Олсоп,
1969]. Начиная с уровня наиболее близкого к аппаратуре, эти уровни
можно поставить в соответствие пяти основным подсистемам внутри
системы управления файлами (рис. 6.1). Каждый уровень реализует
некоторые более гибкие возможности, основанные на возможностях
предыдущих уровней. Первые уровни оперируют преимущественно
с физическими аспектами системы управления файлами, последние
уровни — с логическими ее аспектами, ориентированными на поль-
зователя.
6.1.1. Система ввода-вывода
Работа физических устройств координируется этим первым уров-
нем программного обеспечения. Процессы, охватывающие эту си-
стему, близки к работе аппаратуры. Они осуществляют манипуля-
ции с томами, считывают и записывают блоки информации при об-
мене по заданным адресам оперативной и вспомогательной памяти.
Команды запоминании
а выверки, зависясире
только от логической
структуры, тредуемой
программой, например
„ дать множество
записей с данным
свойством"
Команды запоминания
и выдорки индивидуальной
записи, например
я дать следующую запись
в последовательном
файле"
Логические команды
для радоты с именами
сегментод данных,
например „открыть
файл"
Команды для радоты
о сегментами данных,
например „создать
сегмент"
Физические команды
нижнего у родня,
например „прочитать
вл о к диска"
Ориентированные
на устройства команды
нижнего уровня, например
„перемотать ленту"
Рис. 6.1. Иерархическая система управления файлами.
6.1.2. Базисная система управления файлами
Эта система занимается преобразованием уникального идентифи-
катора файла в объект, называемый дескриптором файла. Дескрип-
тор файла определяет физический адрес файла, а также его длину.
Если файл состоит из множества блоков, дескриптор файла указы-
вает на различные блоки, составляющие данный файл. Базисная
система управления файлами реализует также команды расчленения
файлов на более мелкие подфайлы (команды образования подмно-
жеств).
6.1.3. Логическая система управления файлами
Функция логической системы управления файлами заключается
в определении уникального идентификатора, соответствующего сим-
волическому имени, данному пользователем. Для получения уни-
кального идентификатора данного файла, которому на более низком
уровне соответствует дескриптор, символическое имя интерпрети-
руется по справочнику пользователя. Функция логической системы
управления файлами не связана с физическими свойствами устрой-
ств, на которых хранятся файлы. Запросы пользователей на обслу-
живание данной системой не зависят от устройств.
6.1.4. Методы доступа
Эта система обеспечивает логические методы доступа к данным,
которые могут быть совершенно отличны от физической реализации
размещения данных. Пользователи иногда хотят получать записи
в некотором порядке, не соответствующем явно способу физического
расположения файла в томе. Например, допустим, что в файле лич-
ного состава записи представлены в виде последовательного списка,
упорядоченного по регистрационным номерам системы социального
обеспечения. Последовательный метод доступа предоставляет записи
просто в том порядке, в котором они хранятся. Какой-нибудь поль-
зователь, однако, может пожелать получить доступ к записям по
значению некоторого поля, например такому, как доход. Запрос
пользователя реализуется отображением его собственного метода
доступа (т. е. упорядочения по доходу) в физическую структуру
файла.
6.1.5. Система управления базой данных
Не будучи фактически частью системы управления файлами,
системы управления базой данных являются тем не менее ее естест-
венным расширением. Различные программы могут требовать от
файлов, с которыми они работают, различной логической структуры.
С другой стороны, хранить различные файлы, содержащие одну и
ту же информацию, но имеющие разную структуру, неэкономично.
Система управления базой данных обеспечивает гибкий программный
интерфейс для пользователя по организации доступа к единствен-
ному физическому экземпляру данных в соответствии с различными
логическими структурами. Такая организация дает возможность
разделения одной и той же информации программами, которые тре-
буют различной логической структуры данных.
В последующих разделах каждый из этих уровней будет описан
более детально. Возможности, обеспечиваемые различными уровня-
ми системы управления файлами, варьируются от команд нижнего
уровня, зависящих от конкретных устройств, до команд высокого
уровня, ориентированных на потребности пользователя. Разделение
возможностей по уровням не только помогает лучше организовать
работу над отдельными частями системы управления файлами, но
обеспечивает удовлетворение как потребностей операционной систе-
мы, так и нужд пользователей операционной системы. Хотя эти две
различные функции могут сочетаться в одной системе управления
файлами, как правило, часть системы, предназначенная для про-
цессов операционной системы, слишком сложна для обычных поль-
зователей и недоступна им.
6.2. Система ввода-вывода
Аппаратура ввода-вывода вычислительных машин обычно со-
стоит из иерархической структуры каналов, устройств управления и
самих устройств ввода-вывода. Команда «начать ввод-вывод» в общем
случае указывает устройство и адрес некоторой программы, называе-
мой программой канала, которая хранится в оперативной памяти
и управляет операцией ввода-вывода. Канал выполняет команды
программы канала для осуществления требуемой передачи дан-
ных. Завершение операции или аварийная ситуация вызывают пре-
рывание. При поступлении в процессор прерывания от ввода-вывода
информация о состоянии операции ввода-вывода запоминается. Если
произошла ошибка, можно получить дополнительную информацию
о компонентах состояния, используя команды запроса значений ком-
понент.
Система ввода-вывода состоит из процессов программного обеспе-
чения, соответствующих каждому элементу аппаратуры ввода-вы-
вода и управляющих их работой. Это допускает использование стан-
дартных механизмов связи в системе ввода-вывода, описанных в гл. 2.
Пути связи в таком случае представляют собой внутреннее отобра-
жение аппаратных соединений. Одна из функций системы ввода-
вывода состоит в том, чтобы преобразовать взаимодействие между
процессором и аппаратурой ввода-вывода в стандартный формат
связи. После этого система может рассматривать устройства как
взаимодействующие процессы.
Такой подход имеет три важных преимущества. Во-первых,
программное обеспечение реализуется таким образом, что асинхрон-
ная работа аппаратуры управляется независимыми взаимодействую-
щими процессами. Это значительно облегчает в концептуальном от-
ношении проектирование и реализацию остальной системы, посколь-
ку отличия в скоростях устройств для остальной системы становятся
неразличимыми. Во-вторых, специальные условия, такие, как воз-
никновение ошибок канала, контролируются самым низким уровнем
системы управления файлами. Другими словами, эти задачи решают-
ся программным обеспечением, которое наилучшим образом для
них приспособлено, а для других уровней программного обеспече-
ния указанные проблемы становятся более прозрачными. В-третьих,
вся работа, зависящая от устройств, локализована на самом глубо-
ком уровне системы. Детали связи устройств не затрагивают про-
цессов на других уровнях, где могут быть обращения к вводу-выводу.
Ниже описана возможная организация главных частей системы
ввода-вывода [Атвуд и др., 1972]. На данную организацию сильно
повлияли характеристики аппаратуры IBM, поскольку почти не-
возможно обсуждать системы ввода-вывода независимо от машины.
6.2.1. Система управления каналами ввода-вывода
Эта подсистема состоит из процессов, называемых менеджерами
каналов, причем с каждым физическим каналом связан один менед-
жер канала. Каждый менеджер канала начинает ввод-вывод в своем
канале, посылая каналу сообщение с указанием выполнить програм-
му канала. О выполнении ввода-вывода менеджер канала получает
сообщение от канала, в котором отмечено нормальное или ненормаль-
ное завершение операции. Менеджеры каналов могут быть написаны
с использованием в точности тех же соглашений о связях, что и дру-
гие процессы. Процессы, общающиеся с менеджером канала, ведут
себя так, как если бы они посылали сообщения прямо устройству
управления и получали от него ответы. Следовательно, работа ме-
неджера канала состоит в сортировке получаемых им прерываний;
он реагирует только на те, которые относятся к условиям в канале,
пропуская остальные для соответствующих менеджеров устройств
управления.
6.2.2. Дисковая система ввода-вывода
Дисковая система ввода-вывода включает по одному процессу
для каждого устройства управления дисками и по одному процессу
для каждого дисковода. Для управления (логическими) дисками
используются менеджеры каналов. Каждый диск получает команды
высокого уровня, которые переводятся в соответствующие команды
для менеджера канала. Менеджеры каналов выполняют следующие
команды:
1) разметить диск на блоки в соответствии со стандартной спе-
цификацией системы;
2) прочитать или записать метку тома, однозначно определя-
ющую том на дисководе;
3) записать блок информации из памяти на диск;
4) прочитать блок информации с диска в память.
Такая же организация может быть использована и для других
вращающихся устройств, например для барабанов.
6.2.3. Терминальная система ввода-вывода
Эта подсистема обслуживает интерактивные терминалы анало-
гично службе телефонной связи. Все устройства типа телетайпов
(включая главный пульт процессора) могут рассматриваться как
устройства с цифровым диском. Таким образом, каждый терминал
действует как телефон, который может вызвать систему и затем
может отсоединиться от системы. В продолжение всего времени
связи с системой терминал может передавать и/или получать сооб-
щения.
Для обслуживания терминальной системы ввода-вывода менеджер
канала создает два пути передачи сообщений: путь управления
и путь связи. Путь управления используется прежде всего, чтобы
информировать систему о подсоединении или отсоединении терми-
нала. Путь связи используется для посылки строк данных на тер-
минал.
Терминальная система анализирует первую строку, передан-
ную терминалом (после вызова системы), и решает, какая подсис-
тема или подсистемы (если такие есть) могут общаться с данным
терминалом. Если находится одна и только одна такая подсистема,
путь связи прокладывается непосредственно к ней. После установ-
ления пути связи сообщения от терминала посылаются прямо под-
системе. При наличии нескольких подсистем терминальная система
определяет по характеристикам терминала, каким образом сооб-
щения должны быть распознаны и какой подсистеме переданы.
6.2.4. Периферийная система ввода-вывода
Периферийная система ввода-вывода управляет всеми аппа-
ратными устройствами, кроме дисков, барабанов и устройств типа
телетайпов, которые управляются своими собственными подсисте-
мами. Периферийные устройства требуют отдельного управления
из-за их широко варьирующихся рабочих характеристик. Пери-
ферийная система ввода-вывода использует менеджеры каналов,
которые обслуживают следующие периферийные устройства:
1. Устройства печати, которые принимают команды в форме
«напечатать п строк из памяти».
2. Устройства считывания карт, которые принимают команды
в форме «прочитать п карт в память».
3. Устройства перфорации карт, которые принимают команды
в форме «отперфорировать п карт из памяти».
4. Лентопротяжные устройства, которые принимают команды
в форме
(а) «прямая или обратная перемотка»,
(Ь) «читать п блоков с ленты в память»,
(с) «писать п блоков из памяти на ленту».
Для каждой компоненты есть свой управляющий процесс.
Приведенная здесь организация системы ввода-вывода отнюдь
не полна. Большинство деталей, а их очень много в системе ввода-
вывода, не обсуждается. Для читателя важно понять, что именно
делает система ввода-вывода. Как она это делает, может быть рас-
сказано после подробного изучения специфических характеристик
аппаратуры. Некоторые из этих характеристик будут существенно
меняться в будущих проектах оборудования. Следовательно, в
книге о принципах операционных систем и не стоит углубляться
в эти характеристики.
6.3. Базисная система управления файлами
Система ввода-вывода позволяет остальной части системы по-
сылать физическим устройствам и получать от них данные. Перед
пересылкой данных требуется определить адрес оперативной па-
мяти и физический адрес на устройстве. Для определения физиче-
ского адреса базисная система управления файлами обрабатывает
дескрипторы файлов, которые и дают требуемые физические адреса
блоков, принадлежащих файлу. Кроме того, при помощи связи с
оператором она следит за установкой томов и может быть исполь-
зована для определения подмножеств файла или для расширения
области памяти файла.
Дескриптор файла — это небольшая структура данных, ко-
торая однозначно определяет файл. Обычно он содержит адрес
каждого блока, принадлежащего файлу, и управляющую информа-
цию о том, как пересылать дескриптор и как с ним работать.
Используя специальные команды базисной системы управления
файлами, можно создавать и обрабатывать дескрипторы файлов.
1. СОЗДАТЬ ДЕСКРИПТОР (размещение)
Создает новый дескриптор файла, связанный с областью, оп-
ределенной размещением. Дескриптор файла для целого тома может
быть автоматически дан процессу, владеющему данным томом без
явной команды СОЗДАТЬ ДЕСКРИПТОР. Дескриптор может быть
в дальнейшем поделен на дескрипторы файлов, соответствующие
областям внутри тома с помощью следующих команд.
2. ПОДМНОЖЕСТВО (дескриптор файла, подмножество)
Образует новый дескриптор файла, соответствующий подмно-
жеству данного файла, которое может быть определено, например,
первым и последним словом подмножества. После выполнения этой
команды для ссылки на данное подмножество исходного файла
можно пользоваться новым дескриптором файла.
3. РАЗМЕСТИТЬ (дескриптор файла, размещение)
Создает новый дескриптор файла, соответствующий объеди-
ненной области файла, определенного дескриптором файла, и дру-
гой области, определенной размещением.
4. ОСВОБОДИТЬ (дескриптор файла, размещение)
Возвращает часть файла, определенного дескриптором файла,
в свободную область. Возвращаемая часть указывается раз-
мещением.
Базисная система управления файлами управляет также то-
мами вспомогательной памяти. Следовательно, для выдачи указа-
ний по установке томов она должна организовать путь связи с пуль-
том оператора. Она может дать оператору инструкцию установить
некоторый том на определенное устройство или на любое свободное
устройство. В последнем случае базисная система управления фай-
лами ожидает от оператора сообщения о том, какое устройство
выбрано.
Базисная система управления файлами имеет таблицу томов,
в которой содержится информация о текущем состоянии всех томов
системы. Запись для одного тома может содержать следующую
информацию:
1) имя тома и уникальный идентификатор тома;
2) имя логического устройства, если том установлен, или не-
который признак, если том не установлен;
3) счетчик активных в данный момент файлов в томе;
4) указатель на таблицу, описывающую размещение информа-
ции в томе;
5) информацию по защите тома (например, имя владельца и за-
конных пользователей) и
6) дату создания.
Для управления томами базисная система управления файла-
ми выполняет следующие команды:
1. ЗАПРОСИТЬ (имя тома)
Вызывающий процесс просит систему включить в таблицу то-
мов запись о новом томе. Базисная система управления файлами
проверяет информацию о принадлежности, учете и защите и создает
дескриптор файла для данного тома. Имя тома может быть локаль-
ным именем данного тома для информации по установке. Оно не
должно обязательно совпадать с уникальным идентификатором
данного.тома.
2. ОСВОБОДИТЬ (имя тома)
Базисная система управления файлами освобождает том, заданный
именем тома, от активного использования и модифицирует учетную
информацию, касающуюся владельца данного тома. Процесс, вы-
давший эту команду, должен быть готов предъявить свои права
на владение этим томом по соответствующему запросу.
3. ПРИКРЕПИТЬ (имя тома)
Базисная система управления файлами привязывает к некоторо-
му устройству том, заданный именем тома. Процесс должен ука-
зать свое право на владение устройством или право выдать запрос
на него. Для фиксации изменения состояния тома модифицируется
таблица томов. Если том не установлен, необходима связь с опера-
тором.
4. ОТКРЕПИТЬ (имя тома)
После проверки по таблице томов базисная система управления
файлами открепляет том, заданный именем тома, от устройства.
Затем она дает знать оператору о том, что данное устройство сво-
бодно.
Перечисленные выше команды позволяют базисной системе
управления файлами выполнять две важные работы. Во-первых,
она управляет областями (базисными файлами) томов, заданными
дескрипторами файлов. Во-вторых, она управляет томами, давая
возможность прикреплять и откреплять тома и вводить новые тома
в систему.
При наличии базисной системы управления файлами Операци-
онная система может работать с дескрипторами файлов, выполняя
команды более высокого уровня. Это позволяет системе управления
файлами при получении, например, команды ЧИТАТЬ генериро-
вать правильные команды для системы ввода-вывода. Иногда у
пользователей более высокого уровня возникает также необходи-
мость ссылаться на конкретную область в томе или каким-либо
другим образом обрабатывать информацию, связанную с такой
областью. Возможности по работе пользователей с дескрипторами
файлов могут выбираться при проектировании конкретной системы.
Иногда пользователям нужна указанная возможность, в других
случаях — нет. Пользователям было бы удобнее, например, ис-
пользовать мнемонические символические имена, а не явные де-
скрипторы файлов; в таком случае им бы потребовалась логическая
система управления файлами, описанная в следующем разделе.
6.4. Логическая система управления файлами
Логическая система управления файлами обеспечивает преоб-
разование применяемых пользователем локальных имен в системно-
ориентированные уникальные идентификаторы (т. е. логическая
система управления файлами задает ЭТ-функцию из разд. 4.1).
Кроме того, она готовит файл для операций чтения и записи, вы-
давая команды базисной системе управления файлами.
Каждый пользователь логической системы управления файлами
идентифицируется объектом, называемым поручителем. Поручи-
тель представляет собой постоянную единицу данных, расположен-
ную во вспомогательной памяти, которая содержит учетную ин-
формацию о соответствующем пользователе, включая список фай-
лов. При регистрации пользователя с помощью процедуры «пропис-
ки» система получает информацию, задающую поручителя этого
пользователя.
Поручители могут быть использованы для формирования кон-
текста для интерпретации данного пользователем мнемонического
имени файла. Например, с каждым поручителем может быть свя-
зан отдельный справочник, как показано на рис. 6.2. Справочник
имеет по одной записи для каждого локального имени, заданного
пользователем, которая может ссылаться на один из файлов пору-
чителя. Информация о файле может быть получена в два этапа.
Во-первых, чтобы найти соответствующую запись в справочнике
поручителя, используется локальное имя. Справочник поручителя
определяет идентификатор файла, который указывает на уникаль-
ную запись в главном справочнике всех файлов системы. Таким
образом, каждый пользователь свободен в выборе локальных имен
для тех файлов, которые используются и другими. Поиск соответ-
ствующего уникального идентификатора в свою очередь также ло-
кален для поручителя и, следовательно, достаточно эффективен.
Совместное использование (разделение) файлов важно для работы
любой гибкой операционной системы, так как оно устраняет не-
нужное дублирование данных. В этой главе особое ударение дела-
ется на описании простого механизма разделения. В гл. 7 будут
обсуждаться методы, ограничивающие разделение в соответствии
с требованиями безопасности информации.
В описываемом двухступенчатом доступе по справочникам в
главном справочнике для каждого файла имеется уникальная за-
пись. Запись содержит уникальное для всей системы имя, опреде-
ляющее файл, имя владельца, дату создания, счетчик или список
Рис. 6.2. Двухуровневая справочная структура, (а) Справочники поручителей.
(Ь) Главный справочник.
активных пользователей и дескриптор файла, описывающий об-
ласть, принадлежащую файлу. В разд. 6.7 дан схематичный при-
мер системы управления файлами, где используется идея локаль-
ных и главных справочников.
Логическая система управления файлами реализует команды,
которые позволяют пользователю создавать файл, читать из файла
и писать в файл. Логическая система управления файлами также
требует от пользователя, чтобы он известил ее о своем намерении
работать с файлом. Это извещение осуществляется при помощи
команды ОТКРЫТЬ. Выполняя команду открытия, система управ-
ления файлами определяет положение файла по справочнику и
подготавливается к принятию команд чтения или записи. Порции
данных, которые должны быть считаны или записаны, обычно за-
даются количеством блоков. Блоки не обязательно соответствуют
записям. Это скорее физические блоки, используемые для распре-
6*
деления вспомогательной памяти. Ниже даны примеры команд,
реализуемых логической системой управления файлами.
1. СОЗДАТЬ (имя файла, размер, имя тома [не обязательно])
Делается запрос на образование нового файла с данным именем
файла. Если имя тома указано, файл должен располагаться на
этом томе. Требуется задать также учетную информацию и инфор-
мацию по защите.
2. УНИЧТОЖИТЬ (имя файла)
Делается запрос на уничтожение файла с данным именем файла.
3. ОТКРЫТЬ (имя файла)
Делается запрос на открытие файла с данньш именем файла.
4. ЗАКРЫТЬ (имя файла)
Делается запрос на закрытие файла и отключение пользовате-
ля от файла с данным именем файла.
5. ЧИТАТЬ (имя файла, Ифайл, Мпроцесс, количество)
Делается запрос на считывание заданного количества блоков
в файле с данным именем файла, начиная с блока с номером Ифайл.
Блоки помещаются в связную область памяти, начиная с адреса
Мпроцесс.
6. ЗАПИСАТЬ (имя файла, Ифайл, Мпроцесс, количество)
Делается запрос на запись заданного количества блоков в файл
с данным именем файла. Запись начинается с блока под номером
Ифайл. Данные в оперативной памяти размещены в связной об-
ласти, начиная с адреса Мпроцесс.
Каждая команда может привести к нескольким исходам. На-
пример, команда СОЗДАТЬ может закончиться одним из следую-
щих результатов:
1. Создан файл с данным именем файла в соответствии со спе-
цификациями. В дальнейшем пользователь может обращаться к это-
му файлу.
2. Заданное имя файла совпадает с другим именем, известным
поручителю. Система не может образовать второй файл с тем же
именем.
3. Имя тома не найдено, или том не может быть установлен,
или в томе нет места. Пользователь должен указать другой том для
своего файла.
Пользовательский процесс должен иметь логические средства
для обработки этих различных результатов; в противном случае
условия 2 и 3 будут рассматриваться как непредвиденная ошибка.
6.5. Методы доступа
В предыдущих разделах файл рассматривался как множество бло-
ков информации без учета природы или структуры ее содержания.
Каждой группе пользователей требуется своя собственная струк-
тура информации. Пользователям часто нужно иметь доступ к оп-
ределенным записям в файле, которые задаются некоторыми поля-
ми данных записи. Система может обеспечить нужный механизм с
помощью методов доступа.
Существует несколько способов определения конкретной запи-
си или множества записей в файле, интересующих пользователя.
Простейший способ состоит в использовании положения записи в
файле. Если в логическом файле подразумевается определенный
порядок записей, то можно адресоваться к r-й записи файла. (Ло-
гический порядок записей не зависит от свойств физического устрой-
ства, на котором расположен файл.) Можно также использовать
атрибуты «следующая», «предыдущая» и «текущая», относящиеся
к записи, на которой стоит указатель. Эти атрибуты соответст-
вуют очевидным отношениям, и размер записей здесь не играет
никакой роли.
Более удобный способ ссылки на записи — использование в ка-
честве ключей некоторых полей данных; значение ключа однознач-
но определяет запись в файле. Например, в файле личного состава
ключом может служить регистрационный номер системы социаль-
ного обеспечения. Частичный'ключ — это поле данных, значение
которого соответствует одной, или многим записям, или ни одной
записи. Например, в файле личного состава оклад представляет со-
бой частичный ключ, поскольку количество работников с окладом
10 000 долларов может быть нулем, единицей или другим числом.
Следовательно, любое поле данных может быть использовано в ка-
честве частичного ключа. Чтобы обеспечить доступ к файлу по зна-
чениям определенных полей в записях, эти поля часто выбираются
в качестве ключей или частичных ключей. Например, если записи,
соответствующие работникам, выбираются по регистрационному
номеру системы социального обеспечения, то он и должен быть
объявлен ключом.
Запрос — это языковая конструкция, с помощью которой поль-
зователь может задать требование на поиск информации. Если за-
прос задан в терминах ключей, использованных при организации
набора данных, система может обеспечить для таких ключей более
быстрый поиск указанных записей, чем в том случае, когда эти клю-
чи не были использованы при организации. Предложено много
подходов к реализации поиска записи, требуемой в запросе.
В первом подходе система последовательно просматривает за-
писи, пока не находит все записи, содержащие правильные значе-
ния ключей. Из-за большого числа обращений к диску эта опера-
ция может быть дорогой, поскольку должен быть просмотрен весь
файл. С другой стороны, этот способ очень прост для программиро-
вания. Кроме того, он вполне приемлем для небольших файлов.
При втором подходе для каждого значения ключа система заводит
некоторый элемент с указателями на все записи с подходящим
ключом. Множество всех этих элементов само образует файл,
называемый инвертированным файлом или таблицей индексов. Пред-
положим, например, что в файле личного состава в качестве час-
тичного ключа используется название отдела. Для каждого отдела
множество указателей инвертированного по названию отделов фай-
ла задает всех работников данного отдела. В этом случае инвер-
тированный файл состоит из множества групп указателей, каждая
из которых соответствует одному отделу. Теперь определенные
запросы могут выполняться быстрее, чем при последовательном
методе доступа, особенно те запросы, которые используют ключи,
установленные инвертированными файлами. Однако сами инверти-
рованные файлы занимают значительный объем памяти, и необхо-
димо обеспечить поиск по этим файлам заданных отделов. Больше
того, для поддержания инвертированных файлов необходимы
серьезные усилия, особенно при частых модификациях ключевых
полей.
При третьем подходе система организует цепочку (или мульти-
список) всех записей, которые имеют одинаковые значения опре-
деленного частичного ключа. Например, запись о первом работ-
нике отдела X в файле личного состава имеет указатель на запись
о следующем работнике отдела X и так далее до последней записи.
Эта цепочка наглядна для пользователя, и порядок элементов в ней
может быть произвольным. Указатели, определяющие порядок
элементов в цепочке, устанавливаются системой, чтобы быстрее
обслужить запросы. Например, если пользователь просит записи
обо всех работниках отдела X, система может выбрать первую за-
пись или из словаря, или методом поиска, а затем для извлечения
остальных записей использовать указатели. Для определенных
запросов данная операция выполняется также довольно быстро.
Однако следует иметь в виду, что на указатели расходуется память
и, кроме того, с указателями надо обращаться очень осторожно и
обновлять их при всех изменениях ключевых полей данных в за-
писях.
В реальной ситуации бывает весьма трудно отдать предпочте-
ние одному из трех изложенных выше подходов. Эффективность
системы в значительной степени зависит от типа и частоты обслу-
живаемых запросов. Для оценки различных решений следует при-
менять аналитические средства, моделирование и контроль. Одна-
ко, за исключением вполне определенных применений, начальный
выбор характеристик для реализации оказывается лишь немногим
лучше, чем чисто интуитивный,
Операционные системы обычно предоставляют некоторые стан-
дартизированные методы доступа. Они позволяют пользователю оп-
ределять и извлекать записи из файла при помощи простых команд,
которые возбуждают механизмы поиска или индексации в системе
управления файлами. Фактическая реализация этих механизмов
ясна пользователю.
Методы доступа, обеспечиваемые операционными системами,
имеют две основные характеристики. Они могут быть базисными
или с очередями, а также последовательными или прямыми. Базис-
ный метод доступа — это такой метод, при котором пользователь
должен предусмотреть собственную буферизацию записей, извле-
каемых из файла, как, например, в методе BSAM системы IBM.
Пользователь имеет богатые возможности для изобретения своего
собственного механизма буферизации, подходящего для его при-
ложений. В методе доступа с очередями система имеет стандартную
схему буферизации, как, например, в методе QSAM системы
IBM/360. Пользователь освобождается от заботы по буферизации
своих данных, однако он должен соблюдать соглашения, связан-
ные с механизмом буферизации системы. Последовательный метод
доступа организует записи логического файла в последовательном
порядке. Пользователь может извлекать и хранить данные в запи-
сях файла, обращаясь к ним только последовательно, как в мето-
дах BSAM и QSAM системы IBM. Прямой метод доступа дает поль-
зователю возможность обращаться к записям в файле в произволь-
ном порядке, как, например, в методе BDAM системы IBM. Поль-
зователь прямо ссылается на нужную запись (записи), не указывая
положения записи в файле; в системе имеются необходимые меха-
низмы для определения этого положения и организации доступа
к данной записи (записям).
Прямой метод доступа не исключает последовательного доступа.
Последовательный доступ обычно допускается, но он может быть
не так эффективен, как при использовании собственно последова-
тельного метода доступа. В некоторых случаях последовательный
метод доступа может быть обобщен путем использования индексов
для организации частичного прямого доступа в файле, как, напри-
мер, метод ISAM в системе IBM.
Характеристики методов доступа (т. е. базисный, с очередями,
последовательный или прямой) не связаны принципиально с их
конкретной реализацией или физическими устройствами, на кото-
рых расположены файлы. Они являются логическими характерис-
тиками возможностей, которые предоставляются методами доступа
для пользователей. Разумеется, в реальной практике методы пря-
мого доступа осуществляются для файлов на устройствах с произ-
вольным доступом, таких, как диски и барабаны. При последова-
тельных методах доступа записи на устройствах обычно размеща-
ются последовательно, но это не обязательно. Во всяком случае,
внутренние механизмы метода доступа должны мало касаться поль-
зователя. К сожалению, часто при предоставлении методов доступа
излишне подчеркиваются частности конкретных реализаций.
В существующих системах описано и реализовано большое ко-
личество методов доступа. Большинство прикладных программ
взаимодействует с операционной системой на этом уровне. Методы
доступа традиционно считаются важными для коммерческих при-
ложений.
Даже внутри одной и той же операционной системы существует
значительное дублирование функций. В некоторых современных
методах доступа сделана попытка реорганизовать и объединить воз-
можности их предшественников (например, метод доступа VSAM
системы IBM). В будущем аппаратура сможет, вероятно, непосред-
ственно обеспечивать некоторые возможности методов доступа.
6.6. Системы управления базой данных
Обычно в программах различных пользователей принимаются
различные допущения о структуре и формате файлов, с которыми
они работают. До недавнего времени это требовало существования
многих файлов, даже в том случае, когда информационное содер-
жание файлов было одинаково. Кроме того, нужно было модифи-
цировать программы пользователей при всяком изменении формата
соответствующих файлов. Для достижения определенной степени
независимости программы от файла и для того, чтобы дать возмож-
ность многим различным программам совместно использовать
одну и ту же информацию из единственного экземпляра файла,
было разработано средство, называемое системой управления базой
данных.
Система управления базой данных — это прикладная система,
которая налагает несколько логических структур на некоторую
информацию в соответствии с потребностями пользовательских
программ. Рассмотрим снова файл личного состава. Различные
программы подходят к файлу личного состава с разных точек зре-
ния. Например, программа расчета заработной платы работает с
этим файлом не так, как программа выдачи управленческих отче-
тов. Новые потребности в информации могут возникать и после
создания файла. В этом случае нужно или модифицировать данный
файл, или образовать другой файл. Если файл меняется коренным
образом, старые программы не будут работать. Система управле-
ния базой данных концентрирует в одной части системы все пред-
положения, которые программа должна сделать о структуре обра-
батываемого файла. Учитывая изменяющиеся требования на струк-
туру и обслуживая многочисленные запросы, система базы данных
обеспечивает прикладным программам гибкий интерфейс с обраба-
тываемой ими информацией в файлах. С помощью системы базы дан-
ных каждая программа может работать с таким «логическим» фай-
лом, который ей требуется.
Для реализации различных логических структур, необходимых
пользователям, системы базы данных используют инвертированные
файлы, индексы, ключи и мультисписки. Как правило, системы
базы данных довольно большие и сложные. Некоторые из них пре-
доставляют совершенно независимые языки запросов и возмож-
ности работы с данными (например, система GIS системы IBM).
Другие реализованы как множество вызовов из включающего язы-
ка, такого, как PL/1, КОБОЛ или ассемблер (например, система
IDS на машине GE/Honeywell или система IMS системы IBM). Кро-
ме того, они могут предоставлять средство телеобработки, разре-
шая одновременный доступ многих пользователей к системе базы
данных. В этом случае система называется иногда системой уп-
равления информацией.
6.7. Пример простой системы управления файлами
В этом разделе описана система управления файлами, которая
пригодна для мини-машины с диском. Данная система несколько
напоминает систему UNIX [Томпсон и Ритчи, 1973]. Система ввода-
вывода здесь не обсуждается, чтобы представить разработку более
машинно-независимой. То, что описано в примере, по существу со-
ответствует комбинации очень простой базисной системы управле-
ния файлами и простого метода доступа, основанного на некоторой
логической системе управления файлами.
Каждый пользователь имеет единственного поручителя и свой
собственный справочник файлов. Записи в справочнике поручите-
ля являются указателями на главный справочник, где хранятся фи-
зические адреса файлов. Программа пользователя обращается к
файлу, используя справочник поручителя. Запись в справочнике
содержит следующую информацию (рис. 6.3):
1) символическое имя файла в программе пользователя;
2) номер i записи в главном справочнике;
3) указатель чтения и
4) указатель записи.
Главный справочник состоит из управляющих блоков для файлов.
Каждый управляющий блок (организованный, как показано на
рис. 6.3) содержит следующую информацию:
1) уникальный идентификатор файла;
2) счетчик, указывающий количество пользовательских про-
грамм, для которых файл в данный момент открыт;
3) идентификацию владельца;
Символическое
имя файла
Указатель ~
на главный
справочник
Пользо-
ватель
Ойращается
к файлу
по символическому
имени
Счетчик
Уникальный
идентификатор
файла
Запись
в справочнике
для файла
Управляющий
влек файла
Владелец
Указатель
чтения
Указатель
записи
(а)
Режим
использования
Указатели
на физическую
память
(Ь)
Рис. 6.3. Пример структуры системы управления файлами, (а) Справочник пору-
чителя. (Ь) Главный справочник.
4) режим использования, разрешенный владельцу и другим
пользователям, и
5) группу указателей, каждый из которых ссылается или на
блок памяти, содержащий информацию, или на блок памяти, со-
держащий указатели на блоки информации. С каждым указате-
лем связан бит признака, является указатель косвенным или нет.
Предположим, что блоки памяти имеют по 64 слова и что в груп-
пе указателей может быть до 8 указателей. В пределах этих огра-
ничений можно строить обычные файлы с размерами от 64 до 8*64
слов, а длинные файлы могут содержать до 8*64*64=32/С слов.
Эта система управления файлами дает пользователю возмож-
ность ссылаться на слова в его файле с помощью указателей чте-
ния/записи. Структура справочника позволяет пользователям иметь
в своих справочниках мнемонические имена для общих файлов,
которые совместно используются с помощью главного справочника.
Эти возможности предоставляются в виде следующих команд:
1. /С :== СОЗДАТЬ (Джо, режим использования)
Эта команда предназначена для создания файла. Параметр
Джо — это символическое имя, по которому программа пользо-
вателя будет обращаться к файлу. Система находит первый пустой
блок в главном справочнике и создает управляющий блок. В счет-
чик управляющего блока заносится единица. В блок заносится уни-
кальный идентификатор файла и владельца, а также режим исполь-
зования. Уникальный идентификатор файла присваивается перемен-
ной К. Система создает также запись в справочнике поручителя с
именем файла Джо (СОЗДАТЬ подразумевает также ОТКРЫТЬ),
где указатели чтения и записи устанавливаются на начало файла.
2. Билл ОТКРЫТЬ (К, чтение!запись)
В главном справочнике производится поиск идентификатора
файла, соответствующего значению переменной К. Если он будет
найден, делается проверка, соответствует ли режим использования,
заданный параметром чтение/запись, режиму использования в уп-
равляющем блоке. Если требуемый доступ разрешен, в справочни-
ке поручителя создается запись с именем Билл и счетчик увеличи-
вается на единицу. Программа пользователя теперь может обращать-
ся к данному файлу по имени Билл. Соответствующий указатель
получает начальное значение. Например, указатель чтения ста-
вится на начало файла, а указатель записи — на конец.
3. ЗАКРЫТЬ (Джо)
В справочнике поручителя удаляется запись с именем Джо,
и счетчик в управляющем блоке, соответствующем файлу Джо,
уменьшается на единицу. Если счетчик становится равным нулю,
удаляется управляющий блок. Заметим, что последняя команда
закрытия действует как команда удаления. Если нужно, может
быть также реализована отдельная команда УДАЛИТЬ.
4. пчитать : = ЧИТАТЬ (Джо, буфер, количество)
Цель Люй команды — прочитать информацию из файла, кото-
рый в программе пользователя открыт и назван именем Джо. Па-
раметр количество задает максимальное число слов, которое надо
прочитать, а параметр буфер определяет буфер, куда надо пере-
слать слова. Чтение начинается с текущего положения указателя
чтения и заканчивается по заданному количеству слов или по до-
стижении конца файла. Из файла читается п слов (п не превышает
заданного количества), переменная пчитать принимает значение п,
и указатель чтения увеличивается на п.
. 5. пписать := ПИСАТЬ (Джо, буфер, количество)
Это аналогичная команда для записи в файл. Количество за-
дает максимальное число слов, переписываемых с буфера в файл
Джо. Действительное число записанных слов присваивается пе-
ременной пписать, и указатель записи увеличивается на эту вели-
чину. Если ранее не было команды НАЙТИ, указатель записи ука-
зывает на конец файла. Таким образом, при записи файл растет и
не происходит никакой перезаписи.
6. НАЙТИ (Джо, смещение, признак)
Эта команда пересчитывает указатель чтения или записи по
значению смещения. Параметр признак может принимать одно из
четырех значений со следующей интерпретацией:
признак ~ 0 — указатель чтения пересчитывается от начала фай-
ла;
признак = 1 — указатель чтения пересчитывается от текущего
положения;
признак = 2 — указатель записи пересчитывается от конца файла;
признак ~ 3 — указатель записи пересчитывается от текущего по-
ложения.
В зависимости от значения признака указатель чтения или за-
писи устанавливается в заданное положение и затем пересчитыва-
ется по величине смещения. Задавая признак равным 0 или 2, мож-
но организовать пересчет относительно начала или конца файла,
что часто оказывается легче, чем следить за положением указателя.
7. псообщить : = СООБЩИТЬ (Джо, чтение/запись)
Переменной псообщить присваивается текущее положение ука-
зателя чтения или записи файла Джо.
6.8. Заключение
В данной главе в общих чертах были описаны основные харак-
теристики систем управления файлами и важные критерии для их
проектирования. Системы управления файлами рассматривались
как последовательность уровней программного обеспечения, на-
чиная с уровня аппаратуры:
1) система ввода-вывода, которая маскирует специфические
особенности аппаратуры и обеспечивает передачу сообщений и функ-
ции ввода-вывода в терминах переписи блоков;
2) базисная система управления файлами, которая распреде-
ляет области в томах и управляет томами;
3) логическая система управления файлами, которая позволя-
ет давать символические имена и использовать ориентированные
на пользователей операции;
4) методы доступа, которые реализуют разметку файлов и при
помощи нескольких механизмов дают пользователю возможность
определять и получать доступ к отдельным записям;
5) система управления базой данных, которая обеспечивает
построение нескольких логических структур данных на одном и
том же физическом экземпляре файла.
В заключение с помощью простого примера системы управле-
ния файлами были проиллюстрированы некоторые методы.
Системы управления файлами включены во многие операцион-
ные системы, начиная с ранних систем, ориентированных на ра-
боту с магнитными лентами, и с годами они унаследовали громозд-
кую, красочную и большей частью жаргонную терминологию. Что-
бы пролить какой-то свет на этот клубок противоречивых терминов
и описать некоторые элементарные идеи, необходимы общие поня-
тия. Например, процессы, как основные вычислительные едини-
цы, служат целям описания операций в операционной системе.
В системах управления файлами основные понятия должны были
бы быть сформулированы в терминах структур данных, поскольку
основная функция систем управления файлами связана с управле-
нием данными. К сожалению, еще нет общего соглашения даже по
элементарным понятиям структур данных. Необходимы понятия,
опирающиеся на структуру данных, подобно тому как понятие про-
цессов опирается на вычисления. Управление данными запазды-
вает за наукой о вычислениях в понимании своих основных функ-
ций и операций. Как следствие этого, данная глава могла показать-
ся специализированной, особенно по сравнению с предыдущими
главами. Тем не менее системы управления файлами важны, даже
если они не так элегантны в своих основных концепциях, как дру-
гие, более развитые области вычислительной науки.
Задания
6.1. Являются ли системы управления файлами жалким суррога-
том виртуальной памяти? Обеспечивают ли они какие-то дополни-
тельные возможности? Облегчает ли виртуальная память реализа-
цию системы управления файлами? Обоснуйте свои ответы.
6.2. Какой вы представляете себе величину справочников? Всегда
ли они помещаются в оперативной памяти? Исследуйте различные
способы хранения справочников. Какие методы применяются для
поиска записи в справочнике? Приведите несколько примеров из
существующих систем.
6.3. Для каждого совместно используемого файла в системе реко-
мендуется хранить информацию обо всех пользователях, которые
в данный момент имеют файл открытым. Обсудите сравнительные
преимущества двух методик: вести только счетчик пользователей,
имеющих данный файл открытым в текущий момент, или иметь
список этих пользователей, указанных своими уникальными име-
нами или обратными указателями.
6.4. Рассмотрите систему SUE, описанную в гл. 10. Можете ли вы
заметить влияние аппаратуры IBM/360 на проект системы ввода-
вывода? Какие изменения в организации аппаратуры ввода-вывода
позволили бы упростить систему ввода-вывода?
6.5. Обрисуйте в общих чертах реализацию дескрипторов файлов.
Какие качества аппаратуры желательны для работы с этими дес-
крипторами? Сравните ваши дескрипторы с дескрипторами сегмен-
тов, имеющимися в некоторых машинах фирмы Burroughs.
6.6. Процессу, который управляет томами в операционной системе,
необходимо иметь связь с оператором, который фактически уста-
навливает и снимает дисковые тома. Разработайте форму обмена
сообщениями между оператором и процессом, управляющим томами.
6.7. Совместное использование данных, содержащихся в файле,
может быть осуществлено с помощью копирования. Обсудите срав-
нительные преимущества копирования данных и совместного ис-
пользования единственного файла. Каким образом копирование
упростило бы проектирование системы управления файлами?
6.8. В системе с виртуальной памятью каждый процесс может быть
определен пространством используемых виртуальных адресов.
В этом случае процесс может быть сохранен, даже когда он не ак-
тивен, поскольку пространство его виртуальных адресов сохра-
няется неизменным. Применимо ли в такой ситуации понятие пору-
чителя, описанное в разд. 6.4? Обоснуйте ваш ответ.
6.9. Почему в системе управления файлами важна отдельная ко-
манда ОТКРЫТЬ? (Команда ОТКРЫТЬ могла бы подразумевать-
ся в командах ЧИТАТЬ или ПИСАТЬ.)
6.10. Сделайте обзор различных методов доступа, предоставляемых
фирмой IBM для рядов 360 и 370. Укажите какую-нибудь избыточ-
ность в возможностях, предоставляемых методами доступа. Если бы
вы должны были выбрать единственный метод доступа как базу
для различных приложений, то какой вы бы выбрали? Обоснуйте
ваш ответ.
6.11. Пользователь может работать с записями в файле, явно оп-
ределяя их с помощью указателей или неявно с помощью атрибу-
тов или ключей. Например, он может указать на некоторую за-
пись, а затем, употребляя такие команды, как СЛЕДУЮЩИЙ или
ПОСЛЕДНИЙ, выбрать соответствующую запись. В другом слу-
чае он может задать в одном операторе все записи, которые ему
нужны, например записи с полем оклада, равным 15 000 долларов.
Тогда система может использовать более доступные для пользо-
вателя указатели, чтобы получить эти записи. Обсудите сравни-
тельные достоинства обоих подходов.
6.12. Рассмотрите систему управления файлами, в которой поле
записи может иметь значение «пусто», означающее неопределен-
ность. Опишите в языке программирования средство для работы
со значением «пусто» как возможным значением переменной или
выражения в процессе вычислений. Помните, что проверки во вре-
мя выполнения обходятся дороже, чем во время компиляции.
6.13. В системе управления базой данных команды управления дан-
ными могут задаваться на включающем языке, таком, как КОБОЛ
в системе IBM IMS, или могут включаться в язык, как в системе
IBM GIS. Обсудите сравнительные достоинства обоих подходов.
6.14. Подготовьте сравнительный обзор различных систем управ-
ления файлами, поставляемых с машинами некоторых ведущих
фирм по производству машин.
6.15. Подготовьте обзор систем управления базой данных и их воз-
можностей.
6.16. Внимательно изучите существующие системы управления ба-
зой данных, такие, как системы IMS, GIS, AAS фирмы IBM, сис-
темы TDMS, TOTAL, MR 12000.
6.17. Подготовьте обзор возможностей передачи данных с соответ-
ствующей стоимостью.
6.18. Внимательно изучите сеть вычислительных машин ARPA
Министерства обороны США.
Глава 7
ЗАЩИТА
7.1 . Введение
Система должна уметь защищать пользователей (или процессы)
от умышленного или неумышленного вреда со стороны других поль-
зователей (или процессов). Наивно рассчитывать на то, что пользо-
ватели всегда лойяльны и не способны ошибаться. Пользователь
может причинить вред, затерев свои или чужие программы и дан-
ные или испортив обслуживающую программу, которая нужна всем
пользователям. (Крайняя степень вреда — выведение из строя сис-
темы.)
Всюду ранее в книге под пользователем понимался человек, ко-
торому нужно выполнить некоторые вычисления. Внутри системы
пользователь может быть представлен отдельным процессом, груп-
пой процессов или блоком памяти. В этой главе слово «пользова-
тель» будет употребляться в широком смысле, обозначая те субъек-
ты в системе, которые используют возможности системы для вы-
полнения персональных вычислений.
Защита — это общий термин, описывающий механизмы за-
щиты объектов системы от их окружения. Хорошие механизмы за-
щиты не должны допускать, чтобы один пользователь мешал дру-
гим пользователям. Кроме того, они должны предоставлять поль-
зователю средства для защиты его программ и данных от него са-
мого.
Механизмы защиты неодинаковы в различных системах. Боль-
ше того, они иногда бывают разными для различных частей одной
и той же системы. Так, например, в некоторых системах существу-
ет один механизм защиты в системе управления файлами, другой —
для оперативной памяти и т. д.
В вычислительных системах вся информация располагается на
некоторых устройствах памяти. Следовательно, можно организо-
вать защиту информации, разделив пространство адресов этих
устройств на области и разрешая лишь контролируемый обмен ин-
формацией между ними. Каждая область адресуемого пространст-
ва должна быть защищена от незаконных попыток получить или
изменить информацию со стороны внешнего окружения. В качест-
ве типичного примера рассмотрим защиту в системе управления
файлами. Каждый файл должен быть защищен от пользователей,
которые задают незаконные операции чтения/записи.
Необходимость управления потоком информации между облас-
тями выдвигает две основные проблемы. Во-первых, области ад-
ресуемого пространства должны быть ограждены так называемыми
«стенами» со специальными «воротами» для обеспечения коммуни-
каций. Проникнуть в некоторую область можно только через во-
рота, стены должны быть непроницаемы. Во-вторых, коммуника-
ции должны «охраняться», т. е. с воротами должен быть связан ме-
ханизм контроля, который разрешал бы доступ к областям только
тем пользователям, которые имеют на это право. Стены вокруг об-
ластей адресуемого пространства должны быть связаны с механиз-
мом адресации (например, со страничным механизмом или с меха-
низмом сегментирования). Чтобы избежать потери эффективности,
адресные ссылки внутри области не должны требовать обширных
проверок. Адресные ссылки на объекты вне данной области долж-
ны реализовываться через механизмы, подобные воротам.
Предположим, например, что пользователь имеет множество
адресов, к которым ему разрешен доступ. Каждый адрес, генери-
руемый его программой, интерпретируется и проверяется. Для
сегментированного пространства адресов, в котором каждый сег-
мент имеет начальный адрес и длину, проверка представляет собой
весьма простую операцию. Для каждой адресной ссылки делается
проверка, находится ли она в диапазоне между начальным адресом
и начальным адресом плюс длина. Адресный механизм возводит
стену вокруг всех адресов, находящихся вне границ, заданных на-
чальным адресом и длиной.
Сегменты также могут быть легко защищены. Каждый раз, ког-
да на некоторый сегмент ссылаются через таблицу сегментов, произ-
водится проверка на законность обращения со стороны процесса,
выдавшего ссылку, в соответствии со статусом защиты сегмента.
Аналогичным образом, когда какой-либо процесс пытается полу-
чить доступ к файлу, его запрос проходит через систему управле-
ния файлами, которая проверяет права данного процесса на соот-
ветствие со статусом защиты данного файла. Не должно допускать-
ся никакого способа получения доступа к файлу, минуя систему
управления файлами (т. е. не через ворота). Файл можно рассмат-
ривать и как область адресуемого пространства, и просто как пор-
цию информации в системе, требующую защиты.
Элементы системы, для которых требуется защита, принято
называть объектами [Лэмпсон, 1971]. Другой способ обеспечить
защиту (возвести стену) состоит в том, чтобы держать в секрете
путь, ведущий к объекту. Иначе говоря, объект не защищен, но
его местоположение известно только определенным привилегиро-
ванным процессам. Другие процессы могут использовать для ад-
ресации объекта какое-либо внутреннее имя, но путь, ведущий к
объекту, известен только привилегированным процессам. Такой
механизм не всегда обеспечивает полноценную защиту, поскольку
стена в этом случае обычно не является абсолютно непроницаемой.
Пользователь имеет все же возможность по ошибке или намеренно
получить доступ к объекту и повредить его. Однако в условиях вир-
туальной памяти большой размер пространства адресов делает та-
кое вмешательство весьма маловероятным.
Третий метод возведения стен защиты заключается в примене-
нии методов кодирования. Информация располагается в незащи-
щенной области, но в закодированном виде. Чтобы ее раскодиро-
вать, процесс должен знать ключ к коду, а он сообщается только
привилегированным процессам. В этом случае в качестве ворот к
информации выступает код.
Каждая область адресуемого пространства должна быть защи-
щена монитором защиты, который выполняет роль ворот. Монитор
пропускает через ворота только определенные привилегированные
процессы, разрешая им доступ к области. Мониторы, которые обес-
печивают синхронизацию (см. разд. 2.6.2), могут быть расширены
таким образом, чтобы обеспечивать и защиту. Каждая попытка
извне получить доступ в данную область (т. е. проникнуть через
ворота) должна контролироваться соответствующим монитором за-
щиты. Монитор может быть частью аппаратного или программного
оборудования. Например, в машинах IBM/360 ключи физической
защиты вместе с ключом в слове состояния программы (PSW) вы-
полняемого процесса образуют аппаратный монитор защиты, ко-
торый защищает области памяти размером 2К байтов. С другой
стороны, система управления файлами представляет собой про-
граммный монитор, который, помимо всего прочего, гарантирует
защиту информации на внешней памяти. До сих пор вычислитель-
ные машины не оснащались сложной аппаратной защитой; гибкий
механизм защиты мог быть реализован только программным путем.
Однако машины будущего будут, вероятно, снабжаться все более
широким набором базисных функций защиты, реализованных ап-
паратно или при помощи микропрограммирования.
Монитор защиты логически расположен где-то на пути, веду-
щем к объекту, чтобы иметь возможность контролировать все по-
пытки получить к нему доступ. Монитор может быть локальным для
объекта. Другими словами, каждый объект, требующий защиты,
может иметь свой собственный монитор защиты. Поскольку пра-
вила доступа обычно одни и те же для широкого класса объектов,
локальная организация дублирует значительную часть усилий по
обеспечению защиты. Очевидно, например, что невыгодно иметь
для каждого файла свой собственный механизм проверки статуса
защиты. Альтернативой является создание одного центрального
монитора защиты, который контролировал бы все попытки полу-
чить доступ в системе. Однако, поскольку каждый запрос на до-
ступ должен пройти через этот единственный центральный монитор,
такая схема часто является причиной появления узкого места в
системе. При аппаратной реализации монитора эта проблема
становится не такой острой, но все равно полностью не сни-
мается.
Одним из приемлемых решений является разбиение управле-
ния защитой по группам объектов. Каждый монитор защиты слу-
жит воротами для большого класса сходных объектов. Здесь в ка-
честве типичного примера снова может служить система управле-
ния файлами, которая требует соблюдения правил доступа для клас-
са объектов, называемых файлами.
Помимо опознания процесса, запросившего доступ, монитор
защиты может также исследовать данные, которые он разрешает
передавать. Это обеспечивает дополнительные меры защиты для
защищаемой области, так как монитор может выявить неверные
данные, которые могут нанести вред области. Ясно, однако, что та-
кой контроль может быть произведен лишь за счет увеличения на-
кладных расходов в мониторе.
Одна из наиболее трудных проблем защиты — организация свя-
зи между двумя процессами, которые относятся друг к другу с по-
дозрением. Каждый процесс пытается ограничить запросы на до-
ступ, генерируемые другим процессом, и внимательно исследует
получаемые данные. Важно, чтобы оба процесса пришли к взаимо-
пониманию по поводу обоюдных требований, накладываемых ими
на связь. Они могут установить в качестве монитора защиты тре-
тий, независимый процесс. Он представляет собой нечто вроде конт-
ракта между процессами. Процессы соглашаются подчиняться не-
которому арбитру и в дальнейшем обязуются ничего не менять без
обращения к «вышестоящим властям».
Исследование попыток нарушения механизма защиты ставит
интересный философский вопрос. В большинстве систем запрос
от процесса, не имеющего соответствующих прав, просто отверга-
ется. Монитор защиты может регистрировать попытки нарушений
и, если нужно, сообщать о назойливых нарушителях. Может ока-
заться весьма полезной возможность накладывать на процессы, на-
рушающие защиту, штрафы, чтобы заставить их оплачивать допол-
нительные расходы на «полицейскую службу».
7,2 < Домены и возможности
Понятие области адресуемого пространства является слишком
общим для того, чтобы оно могло быть полезным при описании ста-
туса защиты системы. Нужны исходные принципы, которые по-
могли бы понять, как надо проектировать механизмы защиты.
В сфере защиты различаются пассивные и активные элементы. Эле-
менты, нуждающиеся в защите, называются объектами. Активный
элемент, который желает получить доступ к объектам, называется
субъектом [Грехем и Деннинг, 1972]. Типичный субъект в системе —
это процесс. Будучи активным элементом, процесс генерирует за-
просы на операции над защищенными объектами. Файлы являются
типичными примерами объектов. Субъект и объект с течением вре-
мени иногда меняются ролями. Например, два процесса могут по-
желать установить защиту друг от друга, и в этом случае они оба
попеременно выступают то в качестве объекта, то в качестве
субъекта.
Поскольку различные субъекты иногда получают одинаковые
права в отношении различных объектов, полезно выделить классы
прав доступа в отдельные категории. Отдельное множество прав
доступа называется доменом [Лэмпсон, 1969, 1971]. Домен опре-
деляет контекст защиты, по которому может действовать некото-
рый субъект. Вместо того чтобы связывать права доступа с субъек-
тами или процессами, они связываются теперь с доменами. В этом
случае каждый процесс действует всегда в контексте защиты, оп-
ределяемой некоторым доменом. Другие процессы могут пользо-
ваться теми же правами доступа, когда работают в том же домене.
Процесс меняет свой статус защиты, меняя домен, в котором он
работает. Разделение статуса защиты на домены позволяет обра-
щаться с правами доступа независимо от субъектов, действую-
щих в системе, и обеспечивает тем самым очень гибкое средство для
совместного использования механизмов защиты.
В некоторых системах целесообразно связать с каждым субъек-
том свой домен. При такой организации процессы как субъекты мо-
гут иметь свои права доступа, закодированные в дескрипторах
процессов. В этом случае существенно теряется гибкость. Если ка-
кая-либо процедура в процессе требует статуса защиты, отличного
от статуса самого процесса, она должна быть выделена в отдельный
процесс. Последний процесс возникает лишь потому, что два домена ,
не должны относиться к одному процессу.
Объекты, субъекты и домены идентифицируются уникальными
идентификаторами. Это соглашение необходимо, так как дает мо-
нитору защиты возможность контролировать законность прав до-
ступа. Для обеспечения в системе генерации в течение многих лет
уникальных идентификаторов можно воспользоваться многоби-
товым их изображением (например, из 64 битов). Из соображений
эффективности удобно также иметь уникальные идентификаторы,
которые единственны только в том контексте, в котором они ис-
пользуются. Например, идентификаторы процессов должны быть
уникальны по отношению к другим процессам, но не должны быть
таковыми по отношению к идентификаторам файлов.
Любое конкретное право доступа некоторого субъекта в отно-
шении другого объекта называется возможностью [Деннис, Ван
Хорн, 1966]х). С возможностями можно обращаться, как с любыми
другими понятиями. Например, доступ «только для чтения» в от-
ношении некоторого конкретного файла представляет собой воз-
можность. Доступ «для чтения и записи» к тому же самому файлу —
другая возможность. Так как слово «возможность» используется
также для конкретной структуры данных, кодирующей право до-
ступа, то применение его иногда вызывает путаницу. Всюду, где
использование этого слова будет двусмысленно, абстрактное поня-
тие возможности будет дифференцироваться от ее конкретного во-
площения в программном обеспечении.
Отмена прав доступа — другая сторона проблемы. Иногда для
субъекта удобно принять решение о том, что его права доступа не-
рушимы. В этом случае, если право доступа теряет силу, субъект
может попытаться по ошибке получить незаконный доступ. Аль-
тернативой служит подход, при котором процессу, раздающему пра-
ва доступа, разрешается отбирать их обратно по своему желанию.
Например, менеджеру ресурсов, распределяющему возможности,
дается право отменять полностью или частично возможности контро-
лируемых им ресурсов. Субъект, который теряет возможность, впра-
ве требовать такую защиту, которая сохраняет возможность не-
прикосновенной [Лэмпсон, 1971], или подавать «жалобу» «выше-
стоящим властям» в системе.
В качестве примера использования возможностей рассмотрим
случай, когда некоторому процессу дано право доступа к объекту
не более п раз. Такое ограничение может быть важно для учетных
целей. Существует много различных способов реализации такого
ограниченного права доступа.
1. Процесс получает возможность в форме «пропуска». Монитор
защиты, действуя как учетчик, ведет счетчик, которому вначале
присваивает значение нуль. Всякий раз, когда процесс использует
возможность, счетчик увеличивается на единицу. Когда счетчик
достигает значения п, монитор защиты перестает учитывать дан-
ную возможность.
2. Процесс получает п возможностей, которые рассматриваются
как пачка «билетов». При каждом доступе монитор защиты «от-
рывает билет», отменяя тем самым одну возможность.
3. В структуру данных, реализующих возможность, вводится
числовое поле с начальным значением п. Каждый раз при исполь-
зовании возможности числовое поле уменьшается на единицу. Мо-
нитор защиты перестает учитывать данную возможность, когда
числовое поле становится равным нулю. Этот тип возможности
х) В оригинале capability. Нам известно два варианта перевода этого термина:
возможность и удостоверение. В данном переводе выбран первый вариант, хотя
использование такого слова, как «возможность», в качестве термина создает опре-
деленные трудности при чтении.— Прим, перев.
напоминает «билет», который компостируется после каждого ис-
пользования.
4. Структура данных рассматриваемой возможности исполь-
зуется как указатель для косвенной ссылки на другую возможность,
в которой хранится число п. При каждом случае доступа данная
возможность используется для ссылки на «общую» возможность и
уменьшения счетчика на единицу. Когда счетчик «общей» возмож-
ности становится равным нулю, все ссылавшиеся на нее возможности
становятся недействительными. Такая схема позволяет многим
субъектам совместно пользоваться общим пулом ресурсов, пред-
ставленным «общей возможностью». Данная ситуация напоминает
совместно используемый «банковский счет», а каждая возможность
соответствует чековой книжке.
В данном разделе в общих чертах описаны принципы различ-
ного использования возможностей. Реализация, основанная на
этих принципах, приводится в разд. 7.4. В следующем разделе бу-
дет описан статус защиты системы.
7.3. Описание статуса защиты
Статус защиты некоторой системы может быть описан при помо-
щи простой модели. В любой заданный момент времени имеется
множество доменов Х= {х(1), . ..,х(п)} и множество объектов
У={у(1), . . ., у (т)}. Статус защиты описывается отображением
F: XxY-уА, где множество А-^{А (1), . . ., A (s)} представляет со-
бой множество атрибутов доступа, таких, как «только чтение»,
«чтение и запись» или «только выполнение». Домены рассматривают-
ся независимо от субъектов, и, таким образом, нет необходимости
подробно вникать в особенности действий субъектов. Предполага-
ется, что в любой заданный момент времени существует некоторый
способ связать любой данный субъект с определенным доменом.
Статус защиты отнюдь не является статическим. Домены и объек-
ты непрерывно создаются, уничтожаются и изменяются по вполне
определенным правилам. Кроме того, субъекты меняют домены, в
которых они действует. Модель дает только моментальный снимок
системы в любой заданный момент времени.
Если отображение F (х, у} зависит только от величин х и у, то
статус защиты можно также описать как матрицу, строки которой
задают имена доменов, а столбцы — имена объектов в системе [Гре-
хем, Деннинг, 1972]. Для каждого домена и каждого объекта мат-
рица определяет права данного домена на данный объект. Права
могут задаваться атрибутами доступа, такими, как, например, «чте-
ние» или «модификация». Поскольку, как правило, домен имеет права
по отношению к очень небольшому числу объектов системы, матри-
ца обычно содержит очень большое число пустых позиций. Мат-
ричная модель не такая гибкая, как функциональная, так как она
отражает влияние на права доступа только в терминах имен доме-
нов и объектов. Однако матричную модель можно обобщить, раз-
решив использовать в качестве элементов матрицы процедуры (т. е.
функции от других переменных).
Рассмотрим в качестве примера домен, который имеет права
доступа, относящиеся только к файлам, имеющим менее 1000 за-
писей. В функциональной модели поле защиты каждого файла мо-
жет содержать и размер, и имя файла; тем самым отображение F
перед разрешением доступа может проверять размер файла. В мат-
ричной модели придется ввести специальный атрибут, означающий
«доступ к малым файлам», который должен теперь дополнять эле-
менты матрицы. Если же с каждым элементом матрицы связать не-
которую процедуру, то законность попыток доступа можно прове-
рять с ее помощью. Эта процедура существенно связана с некото-
рой возможностью (например, с «доступом к малым файлам») и
может эффективно реализовать многие ограничения доступа.
В матричной схеме защиты должны запрещаться бесконтроль-
ные изменения элементов матрицы, так как иначе вообще не полу-
чится никакой защиты. Если же права доменов должны изменять-
ся, то и для них требуется защита. Эту защиту можно осуществить,
обращаясь с доменами как с объектами. Матрицу следует расши-
рить, включив в нее столбцы, соответствующие доменам. После
этого можно получать доступ к доменам и изменять их.
При такой организации монитор защиты не обязан нести пол-
ную ответственность за эволюцию прав доменов [Лэмпсон, 1971].
Пусть в матрице доступа А строки соответствуют доменам, а столб-
цы — доменам и объектам. Кроме того, для каждого права доступа
имеются специальные атрибуты, называемые владелец, управление
и признак копирования. Атрибут «управление» какого-либо домена
х (I) над другим доменом х (k) означает, что домен х (i) полностью
контролирует домен x(k). Атрибут «владелец» домена x(i) по отно-
шению к объекту у означает, что объект у принадлежит домену x(t).
Признак копирования разрешает копирование права доступа в
другой домен.
Статус защиты системы управляется следующими правилами
изменения элементов матрицы:
1. Домен x(i) может удалить атрибуты доступа из элемента
А (%(/), у), если он имеет атрибут «управление» над доменом x(j).
2. Домен x(t) может скопировать атрибут доступа А1 в элемент
А (%(/),//), если атрибут А1 находится в соответствующем элементе
А (%(/),//) и для него установлен признак копирования.
3. Домен x(t) может передавать атрибуты доступа элементу
А (%(/),#), устанавливая или нет признак копирования, если до-
мен х (I) имеет атрибут «владелец» по отношению к объекту у.
Предыдущие правила не дают средств для отмены права досту-
па. Чтобы домен мог это сделать, можно ввести следующее правило.
4. Домен х(г) может удалить атрибуты доступа из элемента
Л (х(/)^), если домен x(t) имеет атрибут «владелец» по отношению
к объекту у и, кроме того, домен %(/) не имеет защищенного до-
ступа к объекту у. Домен %(/) принимает предохранительные
меры против отмены его прав, отказываясь признать какие-либо
права доступа, которые не «защищены».
Приведенная выше схема не описывает связи субъектов с до-
менами и перемещения субъектов от одного домена к другому..В ней
не рассматривались также вопросы создания новых доменов, уда-
ления ненужных объектов или доменов из описания статуса защи-
ты. Нужные для этого механизмы должны быть, однако, включены
в любую практическую реализацию.
7.4. Реализация защиты
Схема реализации защиты представляет собой множество про-
грамм и структур данных, которые реализуют аппарат защиты.
Имеется широкий выбор схем реализации, которые могут быть вклю-
чены в операционную систему. Как и в большинстве проблем реа-
лизации, здесь приходится идти на обычный компромисс между на-
кладными расходами, памятью и гибкостью в системе.
Если для представления статуса защиты используется матри-
ца, то простейшая реализация состоит в том, чтобы поместить в не-
которой таблице Т описание статуса защиты, состоящее из трип-
летов [домен, объект, атрибуты доступа]. Если требуется найти
значение элемента А (х, у), поиск ведется по этой глобальной таб-
лице Т. Однако такая реализация обычно неосуществима по сле-
дующим причинам [Лэмпсон, 19711:
1. Таблица Т довольно велика, поэтому ее невозможно хранить
целиком в оперативной памяти. В оперативной памяти должны на-
ходиться только нужные в данный момент фрагменты, и они тре-
буют соответствующей защиты.
2. В такой реализации трудно осуществить объединение объек-
тов или доменов в группы. Так, например, какой-либо общедоступ-
ный файл должен иметь в таблице запись для каждого домена.
3. Часто бывает необходимо получить все объекты, к которым
некоторый домен имеет доступ или по отношению к которым он яв-
ляется владельцем. Таблица Т должна иметь такую структуру,
чтобы запросы подобного рода выполнялись эффективно.
При втором способе реализации все объекты, к которым имеет
доступ некоторый домен, включаются в список, относящийся к
данному домену. В этом списке, называемом списком возможностей,
элементы [у, А (х, у)] представляют собой возможности, соответст-
вующие правам доступа домена х к объекту у. Было бы очень хо-
рошо иметь аппаратную поддержку для быстрой обработки масси-
вов с односторонним доступом (только для чтения), в которых можно
было бы хранить списки возможностей. Однако тот же эффект может
быть достигнут, если хранить все списки возможностей в одной об-
ласти памяти, которая защищена специальным ключом. Доступ
в эту область разрешается только высокопривилегированному мо-
нитору защиты.
При третьем способе реализации в списки объединяются все до-
мены, имеющие доступ к конкретному объекту; каждый такой спи-
сок присоединяется к данному объекту. Элементы такого списка,
называемого списком управления доступом, имеют вид [х, А (х, у)];
элементы задают атрибуты доступа для каждого домена, который
имеет права доступа к объекту у. Для каждого объекта создавший
его субъект задает процедуру и список управления доступом. Про-
цедура ответственна за проверку доменов, которые пытаются по-
лучить доступ к данному объекту.
Четвертый способ реализации использует в качестве механиз-
ма «замок — ключ» уникальные битовые наборы. В каждом домене
имеется список объектов с битовым набором для каждого объекта,
битовый набор (т. е. ключ) служит для идентификации прав досту-
па к данному объекту. С данным объектом связывается список уни-
кальных битовых наборов (т. е. замков), для каждого из которых
указаны права доступа. Если субъект желает получить доступ к
некоторому объекту, он предъявляет определенный битовый набор
(т. е. ключ) монитору защиты, охраняющему данный объект. Мони-
тор устанавливает соответствие ключа с замком, связанным с дан-
ным объектом, и разрешает или запрещает доступ в зависимости
от требуемого вида доступа.
Если считать, что ключи не могут быть подделаны, способ «за-
мок — ключ» эффективен и достаточно гибок. С битовыми набора-
ми, которые соответствуют возможностям, можно действовать со-
вершенно независимо от значений наборов. Кроме того, если вла-
делец объекта захочет отменить или изменить определенные права
доступа, он может просто изменить список битовых наборов (т. е.
замков), связанный с данным объектом.
Помимо имени объекта и своих прав доступа к данному объекту,
каждый субъект должен знать также, где находится объект. Эта
связующая информация обычно не зависит от защиты объекта. Пути
связи могут быть предоставлены системой по запросу каждому же-
лающему свободно и без всякой проверки. Альтернативное реше-
ние заключается в том, что домены должны хранить у себя инфор-
мацию о путях, ведущих к объектам, доступ к которым находится
в их ведении. Иногда, однако, удобно включать связующую инфор-
мацию в структуру реализации защиты. Например, если использу-
ются списки возможностей, пути, ведущие к объектам, могут хра-
ниться в той же области, что и возможности. При выборе схемы за-
щиты легкость построения связующей информации может как при-
ниматься, так и не приниматься в расчет в зависимости от органи-
зации остальной системы.
Последние три способа реализации более выигрышны по ско-
рости, так как для проверки законности доступа они ограничива-
ются более локализованным поиском. Списки возможностей и ме-
ханизмы «замок — ключ» являются прекрасным средством для ко-
дирования связующей информации. Однако механизмы «замок —
ключ» требуют при реализации больше памяти, так как, во избежа-
ние повторения, битовые наборы должны быть достаточно длин-
ными.
Обратимся снова к модели, описанной в разд. 7.3. Права каж-
дого домена х могут быть выражены функцией F (х, y)==fx(y), ото-
бражающей объекты у на множество прав доступа А, где А = {А (1),
. . .,А (s)}, а А (0 может быть «чтение», «запись», «исполнение» и т. д.
Рассмотренные до сих пор схемы реализации являются очень при-
митивными, поскольку функции fx были одинаковыми для всех
доменов х. Но и различные отображения для различных доменов и
объектов все реализуются, по существу, при помощи просмотра
по таблице и сопоставления битовых наборов.
Накладывая некоторые ограничения на функцию fx, можно
предложить более детально разработанные схемы реализации. Для
получения более эффективных схем реализации можно использо-
вать структуру доменов или объектов. Например, предположим,
что домены строго упорядочены по правам доступа; для любых двух
доменов D\ и D2 либо домен D1 имеет все права доступа домена £>2,
либо наоборот. С каждым доменом можно связать его порядковый
номер. Домен с наименьшими правами получает номер, равный 1,
домен с несколько большими правами получает номер 2 и т. д. Каж-
дому объекту приписывается номер, равный наименьшему номеру
домена из тех, которые имеют доступ к объекту. В рамках этой схе-
мы доступ разрешается в том случае, если номер домена больше или
равен номеру требуемого объекта. Аналогичная схема может быть
разработана для того, чтобы отличать различные права доступа к
одному и тому же объекту.
Другой полезный способ состоит в том, чтобы объекты рассмат-
ривались вместе с мониторами защиты, управляющими этими объек-
тами. Каждая возможность (т. е. структура данных) делится на три
части, первая из которых есть ссылка на монитор, вторая — на
объект и третья — на права доступа. Хотя при таком подходе пред-
ставление возможности обычно занимает много места, он имеет свои
преимущества — быстрое опознавание объекта и атрибута доступа,
на которые ссылается данная возможность.
Хотя теоретически возможны разнообразные схемы реализации
защиты, большинство из них на практике приводит к значительным
издержкам. Иногда наилучшим выходом бывает выбор простого
подходящего алгоритма. Сложные схемы могут быть элегантны кон-
цептуально, но они часто имеют много нежелательных побочных
эффектов.
7.5. Передача возможности и формат
Любой аппарат защиты независимо от его сложности можно лег-
ко обойти, если система имеет рыхлую структуру с большим числом
нестандартных интерфейсов. Пользователь-злоумышленник может
получить доступ к информации, используя незаконный путь, кото-
рый предполагается несуществующим, но использование которого
система тем не менее легко допускает. Возвращаясь к аналогии со
стеной и воротами, это явление можно сравнить с такой ситуацией,
когда в стене имеются дыры, но клиентов умоляют проходить че-
рез ворота. Большинство распространенных коммерческих систем
страдает этим синдромом. Обычно нужны серьезные переделки не
только на стадии реализации, но и в основном проекте, пока су-
ществующие в защите бреши не будут заделаны (если их вообще
можно заделать). Следовательно, чтобы сохранить систему, следует
проектировать ее так, чтобы не существовало никаких путей до-
ступа к элементам системы, кроме тех, которые контролируются ме-
ханизмом защиты.
Представленный в данном разделе пример реализует защиту
модифицированным способом «замок — ключ» [Севсик и др., 1972].
В этой схеме процессы однозначно определяются доменами. Отсю-
да следует, что нет необходимости в отдельном понятии домена.
С каждым процессом связан список прав доступа (т. е. список воз-
можностей). Каждый элемент в списке — небольшая структура дан-
ных, которая кодирует некоторые права доступа к некоторому объек-
ту. Эта структура данных на самом деле воплощает абстрактное
понятие возможности. В данном разделе слова «возможность» и
«список возможностей» относятся и к абстрактному понятию права
доступа, и к его конкретному воплощению.
Выбор размера и формата возможностей — одно из основных
решений в отношении механизма защиты. Размер и формат должны
быть такими, чтобы вмещать всю требуемую информацию, но при
этом не расходовать памяти больше, чем необходимо. Переменной
длиной пользоваться неудобно, так как работа с блоками перемен-
ной длины представляет серьезные трудности. Ограничивая фор-
мат условием постоянной длины, нужно следить за тем, чтобы он
был достаточно гибким для согласования требований к защите во
всех частях системы.
Один из подходов заключается в том, чтобы допускать измене-
ние формата в зависимости от монитора защиты, на который ссы-
лается возможность [Севсик и др., 1972]. Возможность имеет пять
полей, два — фиксированной длины и три — переменной длины.
Общий размер возможности зафиксирован (64 бита), но поля внут-
ри возможности могут меняться. Первое поле — «тип» (8 битов),
оно определяет тип возможности. Так как каждый тип возможно-
сти управляется отдельным монитором защиты (т. е. монитор за-
щиты является процессом), поле «тип» однозначно определяет про-
цесс, который породил данную возможность. Второе поле — «фор-
мат» (8 битов), оно определяет, как используется остальная часть
возможности и может ли возможность передаваться или копиро-
ваться; кроме того, второе поле дает указание о том, что должно
случиться с возможностью, если процесс, владеющий ею, будет
уничтожен. Оставшиеся 48 битов делятся на поля трех типов. Ло-
гическое поле состоит из битов, служащих для указания прав до-
ступа. Биты-признаки в логическом поле могут выключаться (тем
самым отнимая соответствующие права) контролируемым образом.
Числовое поле содержит число, означающее обычно размер ресурса,
отведенного процессу в соответствии с данной возможностью. Про-
цессы могут только уменьшать права, заданные возможностью.
Таким образом, числовое поле может уменьшаться или делиться на
части, создавая новые возможности. Увеличить числовое поле или
добавить биты в логическое поле может только монитор защиты,
который управляет данной возможностью. Свободное поле исполь-
зуется по усмотрению монитора защиты для хранения любой нуж-
ной ему информации. Свободное поле может изменяться только
монитором защиты, который указан в типе возможности, так как
только он в состоянии интерпретировать информацию в данном
поле.
Возможности располагаются в списках возможностей, которые
должны быть хорошо защищены с помощью аппаратных ключей па-
мяти. Очевидно, что если бы сами процессы имели доступ к спискам
возможностей, то вся схема защиты оказалась бы несостоятельной.
В целях защиты списки должны храниться в некотором централь-
ном мониторе, который берет на себя управление возможностями.
Описанный в разд. 2.3 стержень может взять на себя эту функцию;
можно также построить специальный монитор. При создании всех
возможностей, работе с ними и передаче используются специальные
команды центрального монитора.
Монитор защиты может создать возможность только соответ-
ствующего ему типа. Монитор защиты дает запрос на то, чтобы
данная возможность была включена в определенный список воз-
можностей; центральный монитор может легко проверить, имеет ли
монитор защиты соответствующее право. Процессу разрешается
инспектировать возможности в своем собственном списке возмож-
ностей, получая в оперативной памяти их изображения. Изображе-
ние возможности процесс не может использовать для подделки прав
доступа, так как данные процессу права записываются в его спи-
сок возможностей только центральным монитором. Записан-
ная центральным монитором информация защищается аппарат-
но, что в значительной степени затрудняет намеренные попытки
изменения.
Важно, чтобы передача возможностей между процессами стро-
го контролировалась. Ясно, что если можно было бы физически
передавать возможности от одного процесса к другому, то стал бы
возможным и подлог. Решение этой проблемы состоит в передаче
не физической структуры данных, а индекса возможности в спис-
ке возможностей. Чтобы передать возможность, процесс просит
центральный монитор переместить одну из его возможностей (на-
пример, z-ю по счету) в список другого процесса. Затем допусти-
мость передачи проверяется по тому биту в поле формата, который
указывает, можно ли передавать данную возможность или нет.
Центральный монитор проверяет этот бит перед перемещением воз-
можности.
Предположим, например, что процесс хочет выполнить приви-
легированную операцию, допускаемую системой управления фай-
лами. Процесс делает запрос и дает индекс своей возможности,
рассчитывая, что ему разрешат выполнить данную операцию. Сис-
тема управления файлами запрашивает у центрального монитора
изображение возможности данного процесса. Если возможность
соответствует требованиям системы управления файлами, послед-
няя выполняет операцию.
Возможности можно использовать также для целей, отличных
от защиты. Рассмотрим базисную систему управления файлами,
которая обеспечивает элементарные операции разбиения файлов на
подмножества и возведения вокруг них стен защиты. Предполо-
жим далее, что все файлы состоят из целого числа блоков по 2 К слов.
Базисная система управления файлами использует возможности
типа «базисный файл», которые имеют одно логическое и три сво-
бодных поля. Первое свободное поле, называемое ТОМ, содержит
ссылку на внутренний идентификатор тома. Два оставшихся сво-
бодных поля, НАЧАЛО и ДЛИНА, определяют начальный
адрес и длину файла. Логическое поле указывает, какие опе-
рации в файле допустимы, например «чтение», «запись», «выпол-
нение».
Базисная система управления файлами использует возможности,
по существу, как дескрипторы файлов. Возьмем, например, ко-
манду ПОДМНОЖЕСТВО (ИНДЕКС ВОЗМОЖНОСТИ, ГНЕЗДО
ВОЗМОЖНОСТИ, НАЧАЛО, ДЛИНА). Если параметры НАЧАЛО
и ДЛИНА не выходят за пределы файла, заданного ИНДЕКСОМ
ВОЗМОЖНОСТИ, то система управления файлами образует но-
вую возможность (т. е. дескриптор файла) для подмножества файла,
определенного параметром НАЧАЛО и параметром ДЛИНА. Но-
вая возможность будет помещена в «гнездо», заданное ГНЕЗДОМ
ВОЗМОЖНОСТИ.
В базисной системе управления файлами возможность исполь-
зуется не только для запоминания такой информации о файле, как
НАЧАЛО, ДЛИНА, ТОМ, но и служит в качестве уникального
идентификатора. Таким образом, в реализации возможностей, не-
обходимых для организации защиты, и дескрипторов файлов, слу-
жащих для идентификации файлов, используется одна-единствен-
ная структура данных.
В качестве второго примера рассмотрим операции чтения/за-
писи, которые должен выполнять менеджер устройства, входящего
в систему ввода-вывода. Менеджер устройства хочет вести учет
таким операциям. Он порождает возможности типа МЕНЕДЖЕР
УСТРОЙСТВА, которые имеют числовое поле, указывающее число
разрешенных операций ввода-вывода. Возможности распределяются
по подсистемам, которые должны выполнять ввод-вывод. После
того как некоторые возможности вручены подсистеме, она полу-
чает право свободно распределять их между связанными с ней про-
цессами, следуя гибкой стратегии выбора решений.
Возможность устройства в конечном счете попадает к процессу
пользователя, который хочет выполнить ввод-вывод. После опера-
ции ОТКРЫТЬ процесс пользователя может получить доступ к
файлу непосредственно через менеджера устройства, которому уже
известно, что процесс пользователя после команды ОТКРЫТЬ
имеет разрешение на чтение/запись. До тех пор пока числовое по-
ле имеет положительное значение, процесс считается «кредитоспо-
собным» в отношении ввода-вывода. Возможность устройства ис-
пользуется для подсчета числа операций ввода-вывода. В данном
случае, имея информацию, закодированную в числовом поле, воз-
можность служит одновременно для измерения и учета, а также и
для защиты.
Проектирование хороших механизмов защиты — трудная за-
дача. Как и в других проблемах, возникающих при проектирова-
нии сложных систем, логически совершенное решение не обяза-
тельно является приемлемым. Решение должно быть разумным и
по затратам. Для некоторых приложений величина накладных рас-
ходов, связанных с защитой, может быть весьма существенной,
особенно если все проверки выполняются при помощи интерпре-
тации. Если механизм защиты очень громоздкий, его будут обхо-
дить и, следовательно, он окажется неэффективным. Значит, по-
мимо соображений удобства и надежности, разработчик средств
защиты должен тщательно учитывать стоимость проекта.
7.6. Безопасность
В последнее время часто обсуждались вопросы управления до-
ступом к привилегированной информации в банках данных общего
назначения. Многочисленные работы касались трех основных ка-
тегорий [Готлиб, Бородин, 1973]. Тайна частной информации оп-
ределяется законодательными и этическими нормами, регулирующи-
ми доступ к информации на индивидуальной основе. Тайна частной
информации является атрибутом человеческого общества. Члены
общества должны сообща (при строго индивидуальном подходе)
решить, каковы их права в отношении частной информации. Сек-
ретность информации подразумевает определенные правила до-
ступа к данным. Секретность в реальном мире относится к данным,
которые по каким-либо соображениям должны быть защищены.
Безопасность информации включает способы и средства, обеспечи-
вающие соблюдение решений по секретности. Другими словами,
эти средства реализуют требования секретности при представлении
данных в вычислительных машинах.
Пусть, например, в некоторой стране сложилось твердое об-
щественное мнение о необходимости сохранения в тайне эмоцио-
нального и физического состояния индивида в прошлом (т. е. его
истории болезни). Это общее мнение должно быть закреплено зако-
нодательным актом или утверждено в качестве руководящего прин-
ципа работы суда. Оно должно быть отражено в специальных за-
конах и постановлениях правительства, касающихся секретности
медицинских данных. Эти законы или решения в свою очередь по-
влияют на проектирование медицинских информационных систем,
заставив разработчиков более тщательно продумывать вопросы
обеспечения секретности при доступе к медицинским записям.
Каждый гражданин, являясь членом общества, разделяет об-
щую заботу о сохранении частных тайн, но у профессиональных
программистов главная забота связана с вопросами безопасности
информации. Общественность должна отдавать себе отчет о труд-
ностях контроля за правами доступа. Кроме того, методы, разра-
батываемые для реализации требований секретности в системах
и банках данных, должны быть приемлемыми по стоимости.
Защита, как она описывалась до сих пор в данной главе, имела
дело с контролем доступа к информации в рамках операционной
системы, не касаясь существа информации. Такие средства являют-
ся внутренними. Внутренние средства защиты используют метки,
замки, ключи и т. д., гарантируя при этом, что доступ к любому
объекту, содержащему информацию, получат только те субъекты,
которые имеют на это право. Безопасность информации включает
некоторые внешние аспекты системы и отличается от внутренней
защиты прежде всего в двух отношениях. Во-первых, рассматри-
вается информационная система в целом, а не только та ее часть,
которая действует на вычислительной машине. Люди являются ак-
тивными элементами информационной системы в целом. Например,
для целей внутренней защиты идентификация пользователя пред-
полагается правильной, в то время как для обеспечения безопас-
ности проверка правильности идентификации становится делом
первостепенной важности. Во-вторых, природа и содержание дан-
ных играют важную роль в определении прав доступа. Механизм
безопасности может основывать свои решения на информации, со-
держащейся в файле, производить проверку данных во время их
передачи или настаивать на подтверждении соответствующих прав
программой, работающей с файлом. Очевидно, система безопаснос-
ти должна быть внутренне защищенной. Но одного этого еще не
достаточно. В данном разделе описаны дополнительные аспекты,
которые, не считая внутренней защиты, относятся к проблеме без-
опасности.
Следующий ниже пример дает представление о потенциальных
требованиях безопасности, налагаемых избирательной секретно-
стью данных [Конвей и др., 1972]. Рассмотрим файл личного соста-
ва большой компании. Файл включает элементы данных о служа-
щих, такие, как фамилия, продвижение оклада, текущий оклад,
оценка квалификации, название отдела, медицинская карта и ре-
гистрационный номер системы социального обеспечения. Некото-
рые возможные решения по поводу секретности, касающиеся до-
ступа некоторого лица к данному файлу, приведены в следующем
списке:
1. Пользователь имеет полный доступ к файлу.
2. Пользователь не имеет доступа к файлу.
3. Пользователю разрешается просматривать любую часть фай-
ла, но запрещается что-либо менять в нем.
4. Пользователю разрешается просматривать только одну за-
пись и менять лишь некоторые поля этой записи.
5. Пользователь может просматривать только поле имени и
поле медицинской карты и менять только поле медицинской
карты.
6. Пользователь может менять только «финансовые» части каж-
дой записи, но делать это разрешается только в определенные часы
дня с особых терминалов.
7. Пользователь может просматривать и модифицировать только
«финансовые» записи, причем только те из них, поле текущего ок-
лада которых не превышает определенной суммы (например, его
собственного оклада).
8. Пользователь может получить «финансовую» информацию в
итоговом виде, а не по отдельным записям.
9. Пользователю может быть выдано поле оценки квалификации,
но только для сотрудников определенного отдела.
Те механизмы защиты, которые обсуждались в предыдущих раз-
делах, могут легко обеспечить удовлетворение первых четырех тре-
бований из приведенного списка. Они могли бы быть использованы
и для удовлетворения остальных требований, но делали бы это край-
не неэффективно. Кроме того, никакие внутренние механизмы не
могут разрешить следующие вопросы:
Как можно гарантировать правильную идентификацию чело-
века? -
Какие меры можно предпринять против перехвата телеграфных
или телефонных сообщений?
Какой контроль можно осуществлять за дисками или лентами,
когда они отключены от вычислительной машины?
Что случится, если система будет работать неверно из-за ошибки
в аппаратном или программном оборудовании?
Хорошая система обеспечения безопасности должна пытаться
решить эти проблемы. Почти невозможно спроектировать «нераз-
рушимую» систему (что касается коммерческих приложений, то
это и не нужно). Важно сделать так, чтобы было очень трудно и до-
рого обойти систему безопасности. Проблему обеспечения безопас-
ности следует рассматривать с позиций всей системы в целом. На-
рушение системы безопасности может с наибольшей вероятностью
произойти в самом слабом звене цепи защиты, которое вовсе не обя-
зательно связано с самой сложной или технически громоздкой опе-
рацией. Уровень безопасности системы определяется уровнем без-
опасности ее самого слабого звена.
Один из самых прямых способов сделать систему безопасности
уязвимой состоит в излишнем доверии по отношению к привилеги-
рованному пользователю. Эта проблема хорошо известна, и при-
меняемые методы противодействия аналогичны тем, которые ис-
пользуются в ручных системах данных. Производится тщательная
проверка персонала, допускаемого к управлению системой, уста-
навливаются высокие штрафы за нарушение правил безопасности,
а вероятность случайного раскрытия информации минимизируется
тем, что важная информация специальным образом помечается.
Обычный метод, применяемый в банковском деле, состоит в том,
что полномочия предоставляются двум служащим. Ответственную
операцию должны выполнять сразу два человека, таким образом,
на противозаконные действия требуется согласие обоих. Развивая
этот принцип, следует разделять функции отдельных людей. На-
пример, оператор, который одновременно является системным про-
граммистом, может легче (чем тот, кто не совмещает эти профессии)
вывести из строя систему безопасности. Наконец, простое присут-
ствие охранника службы безопасности не обязательно решает проб-
лему. Для обеспечения эффективной защиты охранник должен иметь
достаточно хорошее представление о системе безопасности и своих
обязанностях в ней, а также выполнять эти обязанности.
Общее правило состоит в том, чтобы и привилегированный до-
ступ в системе, и информация о работе системы были доступны воз-
можно меньшему числу людей. «Необходимость знать» служит пер-
вым барьером.
Защита от незаконных действий требует опознания пользова-
теля, что, как правило, делается при помощи паролей; но эта
процедура не всегда дает нужный результат. Дополнительное усо-
вершенствование защиты может быть достигнуто более сложными
методами. Например, пользователю можно сообщать уникальный
номер (т. е. одноразовый пароль) при каждом его отключении от си-
стемы. Он предъявит этот номер при следующем подключении. Если
кто-либо другой тем временем подделается под него, предъявив пра-
вильный пароль, то пользователь, по меньшей мере, сможет обна-
ружить из-за ставшего неверным пароля, что произошло нарушение
защиты. В другой схеме используются арифметические преобразо-
вания. Когда при подключении пользователь называет себя, систе-
ма вырабатывает псевдослучайное число х. Пользователь выполня-
ет некоторое простое преобразование Т (х) и отсылает системе ре-
зультат. Система хранит преобразование в сильно защищенной об-
ласти и способна проверять личность пользователя. Заметим, что
величины хн Т (х) предоставляют очень мало информации для оп-
ределения по ним преобразования Т, и, следовательно, данная схе-
ма не восприимчива к перехвату сообщений по линиям связи.
Одноразовые пароли не защищают от лиц, намеренно подсоеди-
няющих терминал к линии законного пользователя. Во избежание
этого, сообщения могут идентифицироваться по уникальным но-
мерам, генерируемым аппаратурой терминала и, возможно, цент-
ральным процессором. В этом случае можно проверять источник
сообщения. Проблема опознавания пользователя связана также с
охраной места физического размещения терминалов и линий
связи.
Любую схему защиты, основанную на паролях, можно обойти,
если у нарушителя имеется достаточно ресурсов и терпения. Поэто-
му управление системой должно быть таким, чтобы дать ей возмож-
ность реагировать на попытки незаконного вмешательства и нака-
зывать за нарушения. Периодические выдачи отчетов о работе с
файлами могут служить для оценки производительности системы и
ее настройки, и, кроме того, они помогают обнаруживать злоупот-
ребления и подделки. При отсутствии в системе средств для реак-
ции на угрозу нарушения какой-нибудь процесс может перегрузить
систему ненужной работой, выдавая в большом количестве неза-
конные запросы на доступ к информации. Каждый раз при этом на
запрос будет даваться отказ, но тем не менее процесс будет требо-
вать определенного внимания системы.
Нарушения системы безопасности при работе с машиной в не-
оперативном режиме можно обнаружить при помощи проверки про-
токолов операций. Такие протоколы расшифровываются с трудом,
но они воссоздают последовательность действий и свидетельствуют
о имевших место нарушениях системы безопасности. Таким обра-
зом, протоколы служат средством, удерживающим от злоупотреб-
лений.
Данные в виде копий на бумаге, на съемных дисках и лентах
также должны быть хорошо защищены, когда они не связаны с ма-
шиной. В некоторой степени безопасность обеспечивается охраной,
сейфами и другими физическими средствами. Необходимо также
следить за информацией, уже ненужной владельцам, но которая
может дать ключ к нарушению безопасности, например старые лен-
ты, ненужная бумага или распечатки состояния оперативной па-
мяти. Обычно оперативная память и ленты после использования
оставляются «грязными». Их следует чистить, расписывая случай-
ными числами, для стирания информации. Даже в том случае, ког-
да информацию необходимо сохранять (снимая копии) для обеспе-
чения целостности, надо предусмотреть меры против незаконного
снятия копий.
При обсуждении внутренней защиты уделялось мало внимания
данным, содержащимся в самом объекте. В то же время хорошая
система защиты должна иногда следить за преобразованием дан-
ных и/или исследовать свойства данных или программ для того,
чтобы гарантировать аккуратное управление режимом доступа.
Чтобы замаскировать информацию, можно пользоваться обра-
тимыми кодировками наиболее важных данных. Это может служить
средством борьбы с перехватом сообщений по линиям связи, с не-
законным доступом к файлам данных и т. д. Кодировка особенно
полезна в том случае, когда систему, обеспечивающую высоки?!
уровень безопасности, нужно присоединить как подсистему к не-
которой системе, в которой вопросам безопасности не уделено до-
статочно внимания. Для затруднения разгадки кода обычно приме-
няются три типа преобразований, которые могут комбинироваться:
замена строк символов, перестановка символов, добавление ключе-
вых символов [Хоффман, 1969].
Иногда желательно управлять доступом к данным не только
на уровне файлов в соответствии с правами пользователя или про-
цесса, но также на уровне записи в соответствии со структурой са-
мих данных. Этот подход помогает избежать увеличения числа от-
дельных возможностей, рсобенно в такой ситуации, когда информа-
ция совместно используется многими пользователями. Так, в опи-
санном ранее примере файла личного состава нельзя ограничить
доступ пользователя к полям оклада свыше 15 000 долларов, если
не учитывать значений данных в поле оклада. С записями, имеющи-
ми поле оклада до 15 000 долларов, можно связать отдельную воз-
можность. Если нужен другой уровень оклада, то потребуется вве-
дение другой возможности. Альтернативный способ заключается
в том, что решения по доступу, зависящему от данных, принимаются
в соответствии с некоторой процедурой монитора защиты, связан-
ной с частным видом доступа, т. е. с особой возможностью. Проце-
дуры, связанные с возможностями, позволяют осуществить защи-
ту в очень общей форме. Однако данный способ является по своей
природе интерпретационным, что влечет определенные накладные
расходы, и, следовательно, он должен использоваться лишь тогда,
когда в этом есть необходимость.
Механизм обеспечения безопасности может включать также про-
верку определенных свойств программ. Рассмотрим, например,
случай, когда программу нужно оградить от попыток собрать ста-
тистическую информацию о данных, с которыми она работает. Для
обеспечения безопасности с соблюдением такого условия необхо-
димо с помощью анализа структуры программы установить соот-
ветствующие правила поведения в отношении данной программы.
Иногда желательно также, чтобы сгенерированные запросы на
доступ проверялись компилятором во время компиляции. В таком
случае компилятор должен быть достаточно надежным, т. е. долж-
на быть доказана его правильность, чтобы из-за ошибки не стал
возможным неверный доступ. Кроме того, средства обеспечения без-
опасности для большинства систем реализуются программным обес-
печением. Важно, чтобы процедуры, обеспечивающие безопасность,
были и защищены, и выверены.
В последнее время проблема безопасности становится крайне
важной. Люди все больше и больше осознают, какое количество
информации накапливается и может быть легкодоступно в инфор-
мационных системах, базирующихся на больших вычислительных
машинах. Раньше нарушения системы безопасности хотя и были
возможны, но встречались в ручных системах крайне редко. Сис-
стемы, базирующиеся на вычислительных машинах, обеспечивают
легкий доступ к данным. Поэтому они должны отвергать незакон-
ный доступ, а не полагаться исключительно на практическую не-
осуществимость или сложность получения информации.
7.7. Заключение
В данной главе была выделена и подробно описана внутренняя
защита. Были предложены различные механизмы защиты. Меха-
низм защиты, отвечающий всем необходимым требованиям, должен
быть одной из. первых целей разработчика систем. Вопросы без-
опасности, бегло очерченные в данной главе, чрезвычайно важны,
хотя и не являются по своей природе сугубо техническими.
Ученых, занимающихся проблемами вычислительной техники
и ее применений, часто критикуют за то, что они окружают свою
деятельность ореолом таинственности. Механизм безопасности в
системе является особо чувствительным звеном. Разработчики си-
стемы, программисты и операторы могут воспользоваться возмож-
ностью нарушения системы безопасности. Если учесть те много-
численные случаи, которые привели к судебному разбирательству,
ясно, что это предположение имеет под собой почву. Следователь-
но, руководство должно с крайней подозрительностью относиться
к непонятным механизмам, предназначенным для работы в системе.
Механизм обеспечения безопасности должен не только правильно
работать, но и быть легкодоступным для неспециалистов в этой об-
ласти, например для управляющих банками.
Задания
7.1. Предположим, что на вашей машине память динамически де-
лится на две части: защищенную и незащищенную. Один бит за-
щиты в каждом слове определяет состояние данного слова — за-
щищенное или незащищенное. Кроме того, любой процесс может
выполняться в привилегированном или в непривилегированном ре-
жиме. Привилегированный режим означает, что процессу доступно
любое слово памяти и что бит защиты любого слова может быть из-
менен. В непривилегированном режиме процессу доступна только
незащищенная память и бит защиты менять нельзя. Придумайте
такой метод, который обеспечил бы для каждого процесса защиту
его собственной области памяти программным путем при условии,
что система имеет произвольное число процессов.
7.2. Предположим, что мы приписываем каждому процессу X не-
который номер %, а каждому объекту Y — некоторый номер у.
Затем реализуем защиту по следующей схеме: «процесс X имеет
доступ к объекту У, если х>у». Какую структуру на права доступа
налагает данная реализация? Соотнесите ее с кольцами защиты си-
стемы MULTICS [Шрёдер, Зальтцер, 1971]. Придумайте другой спо-
соб, который приведет к древовидной структуре. Проанализируй-
те динамические характеристики таких схем.
7.3. Предположим, что оперативная память машины не имеет ап-
паратной защиты, как, например, в случае небольшой мини-маши-
ны. Обрисуйте в общих чертах последовательность шагов, необ-
ходимых для построения разумной системы защиты. Можно ли
в таких условиях придумать какой-нибудь способ защиты инфор-
мации на внешней памяти?
7.4. Предположим, что в вашем распоряжении имеется вычисли-
тельная машина, на которой используется для программирования
один язык. Какие свойства вы могли бы включить в компилятор,
чтобы гарантировать защиту пользователей друг от друга?
7.5. Какие свойства аппаратуры требуются для эффективной ра-
боты с возможностями? Набросайте проект машины с аппаратной
реализацией возможностей. Могут ли данные возможности служить
для других целей, кроме защиты?
7.6. В любой системе имеется некоторое количество более или ме-
нее общедоступных объектов, т. е. таких, которые могут читать поч-
ти все процессы, а изменять — только небольшое число процессов.
Придумайте метод для правильной защиты этих объектов с мини-
мальными накладными расходами.
7.7. Рассмотрим систему, где субъектами защиты являются про-
цедуры. Придумайте способ привязки к любой процедуре некото-
рого домена. Если одна процедура желает обратиться к другой про-
цедуре, вызывающая процедура должна передать свой домен вызы-
ваемой процедуре, после чего последняя может осуществлять до-
ступ к нужным объектам. Каким образом можно передать домен в
качестве аргумента при вызове процедуры?
7.8. Приведите пример, когда в системе защиты важна способность
отменять или ликвидировать возможность. Приведите другой при-
мер, когда отмена возможности может породить серьезные проблемы.
7.9. Составьте список возможных прав доступа (например, «толь-
ко чтение», «чтение/запись»), которые могут применяться для за-
щиты различных объектов в системе. Допустим, что эти права
закодированы в логическом поле возможности. Какой длины же-
лательно было бы иметь логическое поле? Обоснуйте ваш ответ.
7.10. Рассмотрим процедуру, подсчитывающую подоходный налог.
Эта процедура может вызываться только теми пользователями, чей
облагаемый налогами доход не превышает 15 000 долларов. Величи-
на облагаемого налогом дохода сама получается как промежуточ-
ный результат выполнения процедуры подсчета подоходного на-
лога. Кроме того, данная процедура не должна сохранять никакой
информации о налоговом положении любого данного индивида.
Опишите коротко механизм, реализующий решение задачи вычисле-
ния налога при заданных условиях.
7.11. Рассмотрим основную схему реализации защиты, в которой
отдельные записи хранятся в виде <субъект, объект, права до-
ступа>. Опишите вкратце способ быстрого получения доступа к
записям, относящимся к конкретным объектам или субъектам. Ка-
кие аппаратные средства могли бы быть полезны для вашей реали-
зации?
7.12. Проанализируйте требования в отношении памяти для каж-
дого из четырех способов реализации, описанных в разд. 7.4.
7.13. Предложите три хороших способа идентификации пользова-
теля. Для каждого из них найдите ситуацию, в которой данный спо-
соб не будет достигать цели. Если какой-либо субъект в системе
может присвоить себе чужое имя, то система защиты может быть на-
рушена. Например, если некоторый процесс может выдать себя за
процесс, воплощающий одно из средств системы SUE (см. гл. 10),
то он может самовольно изменять возможности, связанные с дан-
ным средством. Опишите в общих чертах последовательность ша-
гов, которая обеспечит точную идентификацию «личности» по край-
ней мере среди системных процессов.
7.14. Докажите, что для любого множества доменов и объектов чис-
ло записей в списке возможностей, списке управления доступом и
в таблице одинаково.
7.15. Подготовьте обзор аппаратных средств защиты памяти, Оце-
ните достоинства регистров с началом и длиной, ключей защиты,
колец защиты системы Honeywell-MULTICS, возможностей си-
стемы ВСС-М1 ит. д.
7.16. Подготовьте обзор по различным механизмам защиты, дейст-
вующим в разных частях большой операционной системы, такой,
как система Burroughs МСР, система IBM OS/360 или система CDC
Scope.
7.17. Подготовьте обзор об использовании вычислительных машин
для сохранения тайн отдельных членов общества.
Глава 8
ПРОЕКТИРОВАНИЕ
8.1. Введение
Операционные системы представляют собой довольно большие и
сложные системы программного обеспечения. Поэтому их нельзя
разработать при недостаточно строгом подходе к организационным
вопросам, что часто допускается при создании небольших программ.
Проект должен быть ориентирован на получение операционной сис-
темы с определенными свойствами при заданных ограничениях по
времени и ресурсам. В качестве первого шага любой серьезной
работы необходимо сформулировать в письменной форме некоторые
предложения, касающиеся проекта. Это утверждение справедливо,
независимо от источников финансирования проекта. По крайней
мере, предложения так же служат для внутренней документации,
как и для представления целей проекта во внешнем мире.
Предложения должны включать целевые характеристики проек-
та в терминах общности, эффективности и надежности системы. Не-
обходимо ознакомиться с литературой, относящейся к данной теме.
Следует использовать опыт других разработок везде, где только
возможно. Если цели противоречат друг другу, нужно рассмот-
реть их относительные приоритеты. Должен быть описан в общих
чертах метод проверки полученной системы на соответствие уста-
новленным целевым характеристикам и критериям приемки. Долж-
ны быть представлены такие спецификации системы, как функции
основных средств и общая внутренняя организация. В предложения
нужно включить оценки временных затрат и финансовых расходов,
необходимых для выполнения проекта. Должны быть четко уста-
новлены потребности по контингенту исполнителей; при этом
следует принять во внимание реальный уровень работников в дан-
ной организации и возможность получить помощь извне. Нужно
подготовить график работ с большим числом контрольных точек,
чтобы оценивать по ним продвижение вперед; следует также опре-
делить в общих чертах организацию коллектива разработчиков.
Особое внимание в предложениях должно быть обращено на те
выгоды, которые будут получены в результате выполнения проекта,
даже в том случае, если решение начать работу над проектом уже
принято по причинам нетехнического порядка, например из сооб-
ражений рыночной конъюнктуры. Люди охотно участвуют в работе,
которая кажется им важной и интересной.
Все главные разработчики проекта должны принимать участие
в написании предложений. Важно, чтобы у них с самого начала
была личная заинтересованность в проекте. Предложения долж-
ны широко обсуждаться среди участников проекта и внутри всей
организации. Заинтересованных или ответственных лиц следует
просить прокомментировать содержание предложений. В случае
финансирования извне предложения служат реальным основанием
для получения денег.
Официально работа над проектом начинается после того, как
предложения написаны и приняты. Участники проекта должны
выбрать общий подход к проектированию, которым они будут ру-
ководствоваться в своей работе. Для проектирования и изготовле-
ния системы нужно позаимствовать или создать заново язык про-
граммирования и средства, облегчающие ведение документации и
отладку. Только после завершения этих предварительных работ
может реально начаться работа по проектированию.
В данной главе описаны в общих чертах некоторые различные
подходы к проектированию. Ни один из них не является абсолют-
но совершенным и не дает полной гарантии успеха. Читатель дол-
жен сам судить о том, какую методологию проектирования он дол-
жен выбрать для разработки, учитывая требуемые свойства систе-
мы, конкретные условия реализации и, наконец, что также очень
важно, свои личные вкусы.
8.2. Методология проектирования
Проектирование — это творческий процесс. В проектировании
операционных систем не существует точных правил, которыми сле-
довало бы руководствоваться. На основе изучения собственного
опыта или опыта других можно решить, какие приемы содействуют
построению хорошей системы и каких трудностей следует избегать.
Однако имеется несколько общих положений и общих подходов,
которыми можно руководствоваться.
Л4етодология проектирования программного обеспечения быстро
развивается. Принципы проектирования программного обеспечения
в определенной степени совпадают с принципами проектирования
во многих других областях. Методология проектирования в других
науках иногда с точностью до терминов применима и в проектиро-
вании программного обеспечения (например, планирование за-
стройки городов [Александер, 1964]). Однако есть принципы, отно-
сящиеся специально к проектированию систем.для вычислитель-
ных машин. В этом разделе будут рассмотрены некоторые такие
методы, которые используются в проектировании и реализации опе-
рационных систем.
Можно сказать, что (почти по определению) процесс проекти-
рования подразумевает принятие ряда решений о форме и содержа-
нии предмета проектирования. Метод проектирования должен по-
мочь разработчику в упорядочении принимаемых им решений. Зна-
ние того, что каждое из его решений принято в надлежащем месте
и в наилучшее время, придает разработчику большую уверенность
в правильности этих решений. Кроме того, метод проектирования
должен помочь разработчику сконцентрировать свое внимание на
определенных аспектах или частях проектируемой системы, взятых
по отдельности. Это особенно важно в операционных системах,
где сложность системы заранее исключает всякую возможность
охватить сразу все детали. Тем не менее разработчик должен точно
понимать общие характеристики всей системы, по мере того как
они проясняются во время проектирования.
Наиболее мощный инструмент, дающий разработчику возмож-
ность справиться со сложностью системы,— это понятие абстракции.
Абстракция представляет собой описание системы или части систе-
мы, в котором не указываются абсолютно все детали. Абстракция
обеспечивает разработчику общий, «макроскопический» обзор систе-
мы. В силу этого она дает представление о глобальных связях и
свойствах основных элементов системы, которое трудно достичь,
когда имеются все подробности.
Каждое описание, если это не физический прототип описывае-
мого объекта, должно быть абстракцией. Описание вычислитель-
ной системы, например, не будет содержать никаких деталей, кро-
ме описания основного аппаратного оборудования и характеристик
программного обеспечения. Структура электронной схемы не за-
трагивается этим описанием. С этой точки зрения можно сказать,
что ни одно описание физического объекта не является абсолютно
полным, если в качестве него не фигурирует сам объект.
Абстракции не представляют собой ничего нового; они давно
используются в математике. Одна из первых абстракций, изучаемых
студентами,— это отделение арифметических свойств чисел отдан-
ного количества физических величин, которые они представляют.
Например, числительное 5 является абстракцией корзины с пятью
яблоками.
Не существует такого понятия, как вполне определенная, един-
ственная абстракция конкретной системы. Для каждой системы
имеется много возможных абстракций. Каждая абстракция дает
разработчику различную точку зрения на то, как выглядит система
и что она делает. Абстракции одной системы, однако, могут быть
тесно связаны. Так, например, одна абстракция а (2) может быть
уточнением другой абстракции а(1). Если абстракция а(2) уточняет
абстракцию а(1), то абстракция а (2) описывает все, что описывает
абстракция я(1), но уровень детализации в абстракции я (2) всегда
не меньше, чем в абстракции а(1). Другими словами, абстракция
а (2) является равномерно более детализированным описанием,
чем абстракция я(1).
Пусть а(1), а(п) — такой ряд абстракций, что для каждого
i абстракция a(i+\) — уточнение предыдущей абстракции а (Г).
Каждая абстракция а (/) представляет собой полное, хотя и не обяза-
тельно подробное, описание всей системы. При увеличении номера
i возрастает детализация описания. Когда абстракции упорядочены
таким способом, имеет смысл говорить об уровне абстракции,
т. е. о степени детализации описания. Высокий уровень абстракции
содержит очень мало подробностей (т. е. большую степень абстрак-
ции). Низкий уровень абстракции содержит много подробностей.
Уровень абстракции — относительное понятие. Нет никакого смысла
говорить о высоком уровне абстракции, если соответствующее опи-
сание не сравнивается с другим, более детализированным описанием.
Тем не менее описания вычислительных систем можно разделить
на два четко различимых уровня детализации. Когда говорят об
описании системы высокого уровня, обычно имеют в виду общие
характеристики системы, не учитывающие многих деталей структуры
системы. Описание системы низкого уровня, как правило, принима-
ет в расчет машинные команды и, возможно, особенности структуры
аппаратного оборудования. Следовательно, можно говорить о высо-
ком и низком уровне описания системы, не указывая точно, по от-
ношению к чему уровень высокий или низкий. Ясно, что аппара-
тура подразумевает низкий уровень, а программное обеспечение —
высокий.
Рассмотрим систему управления файлами как модуль операци-'
онной системы. Один способ описания свойств системы управления
файлами состоит в том, чтобы перечислить названия всех команд,
которые она выполняет, и указать функцию, выполняемую каждой
командой. Это довольно высокий уровень, макроскопическая абст-
ракция системы управления файлами. Такая абстракция дает основ-
ное представление о том, что делает система управления файлами и
как остальная часть операционной системы может ее использовать.
Рассмотрим теперь совокупность общающихся друг с другом про-
цессов, которые составляют систему управления файлами. Эти
процессы вместе образуют другую абстракцию, которая довольно
общим образом описывает внутреннюю структуру системы управле-
ния файлами. Каждый процесс системы управления файлами может
рассматриваться как отдельный элемент, состоящий из множества
структур данных и множества процедур. Неформальное описание
всех этих процедур и структур данных, представленных в каждом
процессе, образуют еще более низкий уровень абстракции системы
управления файлами. Каждая процедура и структура данных может
быть более подробно описана на языке программирования, напри-
мер на АЛГОЛе. Такие описания представляют еще одну абстрак-
цию системы. Эта последняя абстракция имеет то отличие, что ее
можно считать автоматически транслируемой на язык машины.
Теперь абстракция начинает терять свой абстрактный характер.
Она уже является конкретным представлением системы управле-
ния файлами, а не абстрактным описанием ее свойств.
Второе основное понятие проектирования, тесно связанное с
абстракцией,— это виртуальная машина. Виртуальная машина
представляет собой набор элементарных операций, которые описы-
вают работу системы или части системы. Машина называется «вир-
туальной» потому, что она не обязательно должна быть воплощена
в аппаратуре. Например, язык АЛГОЛ описывает виртуальную
машину. Виртуальная машина языка АЛГОЛ обычно реализуется
с помощью компилятора с языка АЛГОЛ, который отображает
язык АЛГОЛ в язык машины. Машинный язык также описывает
виртуальную машину. Эта виртуальная машина, однако, реализу-
ется как реальная машина.
Аналогично уровням абстракции можно рассматривать уровни
виртуальных машин. Чем ниже уровень виртуальной машины, тем
ближе она к аппаратуре. Виртуальная машина языка АЛГОЛ нахо-
дится на более высоком уровне, чем виртуальная машина машинно-
го языка. Виртуальная машина реализуется, как правило, некото-
рой частью программного обеспечения, действующего на другой
виртуальной машине. Компилятор с языка АЛГОЛ реализует язык
АЛГОЛ, работая на аппаратуре с машинным языком. Система уп-
равления файлами, написанная на языке АЛГОЛ и работающая
на виртуальной машине языка АЛГОЛ, реализует виртуальную
машину, которая характеризуется командами системы управления
файлами. Если пользователь данной системы «видит» только компи-
лятор с языка АЛГОЛ и систему управления файлами, то он будет
работать на виртуальной машине, которая понимает предложения
языка АЛГОЛ и команды системы управления файлами. Если он
сам создает пакет программ для статистического анализа, то поль-
зователь его пакета будет иметь дело с виртуальной машиной,
которая делает статистический анализ. Таким образом, каждый
новый слой программного обеспечения реализует новый (более
высокий) уровень виртуальной машины.
Уровни виртуальных машин и уровни абстракций связаны меж-
ду собой. Абстракция системы — это ее описание на некотором
языке. Степень детализации, допускаемая данным языком, характе-
ризует уровень абстракции описания, сделанного на этом языке.
Допустим, например, что некоторая система описана и на языке
АЛГОЛ, и на языке ассемблера. Первое описание, очевидно, будет
иметь более высокий уровень, чем второе, так как описание на язы-
ке АЛГОЛ менее детализировано. Как и все языки программиро-
вания, АЛГОЛ и язык ассемблера описывают виртуальные маши-
ны. Любой язык, используемый для описания системы, определяет
также некоторую виртуальную машину, а именно ту машину, ко-
торая может выполнять данный язык. Но это только другой способ
выразить ту мысль, что данный язык представляет собой инстру-
мент для описания данной системы на некотором уровне детализа-
ции. Язык, который определяет виртуальную машину высокого
уровня, может быть использован для генерации описаний систем
с высоким уровнем абстракции. В конечном счете в ряду виртуаль-
ных машин высокого уровня могла бы быть такая машина, которая
способна выполнять предложения естественного языка. На такой
виртуальной машине, понимающей английский язык, можно было
бы выполнить описание системы на английском языке и получить
работоспособную версию системы!
Не имеет смысла спрашивать о том, каковы основные модули и
строительные блоки некоторой системы. Это сильно зависит от того
уровня абстракции, на котором она рассматривается. Описание
высокого уровня использует строительные блоки, отличные от тех,
которые используются в описании низкого уровня. В зависимости
от языка, на котором описывается система, эти строительные блоки
могут быть процедурами, процессами, функциональными модулями,
подсистемами и т. д.
Используя понятия абстракции, уточнения и виртуальных ма-
шин, разработчик может легче сосредоточить свое внимание на
отдельных частях системы, не упуская из поля зрения ее общую
структуру. В последующих разделах описаны различные' методы
упорядочивания решений, принимаемых при проектировании, в
которых используются описанные понятия.
8.2.1. Структурное проектирование
Структурное проектирование обычно подразумевает использова-
ние структур для разделения различных частей системы. Каждая
часть при этом может проектироваться отдельно. Один из наиболее
традиционных методов проектирования операционных систем сос-
тоит в том, что проект каждого основного модуля системы выполня-
ется отдельно; этот подход иногда называется модульно-интерфейс-
ным. Анализируя существующие системы, можно заключить, что
операционная система состоит из системы ввода-вывода, планиров-
щика времени процессора, менеджера памяти, системы управления
файлами и т. д. Каждый модуль выделяется и описывается (обычно
по английски), кроме того, определяется его интерфейс с другими
модулями. Модули и их взаимные связи образуют абстракцию систе-
мы высокого уровня. После этого этапа для дальнейшего проекти-
рования и реализации модули рассматриваются по отдельности.
Такая же процедура может быть повторена в отношении какого-
либо одного модуля системы, и последующую работу над модулем
можно расчленить на индивидуальные задания по программирова-
нию. После того как все эти модули спроектированы и реализова-
ны, они связываются воедино в соответствии с заранее определенны-
ми интерфейсами.
Соблюдение правильного интерфейса представляет собой серь-
езную проблему в модульно-интерфейсном подходе. Модули и их
интерфейсы обычно описываются весьма неформально и неточно.
Поэтому, хотя отдельные модули и пишутся в соответствии с задан-
ными спецификациями, часто оказывается, что в них заложено
неверное представление об операционном окружении. И когда моду-
ли связываются вместе, они не взаимодействуют должным образом.
Логическая структура и внутреннее представление некоторого эле-
мента данных, совместно используемого многими модулями, могут
быть не одинаковыми в разных модулях, использующих этот эле-
мент. После того как модули получены в коде машины, разрешение
возникших конфликтов может оказаться чрезвычайно трудным де-
лом. Иногда необходимо даже писать специальную программу толь-
ко для того, чтобы исправить интерфейс между двумя модулями.
Для автоматизации решения проблемы взаимодействия модулей
были предложены специальные системы [Вайсман и Стэйси, 1973].
В принципе, если интерфейс полностью специфицирован, в этом
отношении не должно возникать трудностей. К сожалению, однако,
первоначальный общий проект и планирование редко доводятся до
такого уровня детализации, когда используется язык программи-
рования. В результате важные решения, которые должны были
быть приняты опытными разработчиками в начале работы над про-
ектом, отодвигаются внутрь модулей. В конечном счете программис-
ты принимают решения, имеющие глобальные последствия, бази-
руясь на очень ограниченной и узкой точке зрения на систему.
Решения могут приниматься и чрезвычайно квалифицированными
людьми, но не в тот момент, когда нужно. Например, если такой
важный модуль, как менеджер операторского терминала специфи-
цирован недостаточно полно, другие модули могут делать разные
предположения о том, как осуществлять связь с операторским тер-
миналом. Исправление такой ошибки может оказаться сложным
делом. Это тот случай, когда решения принимаются в неверном по-
рядке. Хороший метод проектирования должен помочь разработчику
установить правильный порядок принятия решений.
Правильное определение и выделение модулей представляет со-
бой трудную задачу. Тесно связанные между собой части системы
должны входить в один и тот же модуль. Было предложено считать
мерой связности двух частей системы число предположений, которые
одна часть должна делать относительно другой части [Парнас,
1971]. Слишком много или слишком мало информации об окруже-
нии, в котором работают соседние модули, может иметь плохие по-
следствия при проектировании модуля. Рассмотрим, например, мо-
дуль А, работающий со структурой данных. Соседний модуль В
должен знать точный протокол для связи с модулем А. Однако он
не должен знать всех подробностей о локальной структуре данных
модуля А. Парнас утверждает, что при проектировании одного
модуля неформальное использование информации о внутренних спе-
цификациях других модулей может оказаться вредным [Парнас,
1971]. Так, пусть в предыдущем примере модуль В использует
информацию о локальной структуре данных модуля А. В этом
случае, если модулю А потребуется изменить свою организацию,
модификация модуля В может оказаться весьма неприятным делом.
Неверное представление модуля В о структуре данных модуля А
может не проявиться до тех пор, пока вся система не выйдет из
строя.
Модульно-интерфейсный подход — один из методов структурно-
го проектирования. Спецификации модулей и их интерфейсов дают
структурную основу для проектирования каждого модуля и всей
системы в целом. Рассмотрим в качестве аналогии проектирование
моста. Проектировщик знает, что мост состоит из различных частей,
таких, как платформа, фундамент и опоры. Следовательно, он может
выделить отдельные части моста и проектировать их отдельно.
Кроме того, он должен решить, как следует соединить эти отдель-
ные части. Если возникнут какие-либо трудности при соединении
частей, то трудно будет построить мост даже в том случае, когда
все части соответствуют своим индивидуальным спецификациям.
Потребуется найти особые решения, чтобы соединить все части.
Разработчики программного обеспечения часто начинают работу
с очень грубого и неполного наброска схемы системы и преждевре-
менно обращают свое внимание на детали отдельных модулей. От-
сюда получается, что решения, влияющие на систему глобальным
образом, принимаются не из тех предпосылок, из которых нужно,
и без ясного понимания их последствий. Преждевременная реализа-
ция приводит к неустойчивости систем программного обеспечения,
которая часто требует огромных усилий по поддержанию системы.
К сожалению, эта ситуация встречается удручающе часто.
В следующих разделах будут описаны два метода проектирова-
ния, основанные на структурном принципе и принципе абстракции.
В сущности они сходны с модульно-интерфейсным подходом. Одна-
ко они в значительной степени ограничивают способы, при помощи
которых модули могут как разделяться, так и соединяться вместе.
Эта организация вынуждает следовать определенному порядку
принятия проектных решений. И хотя здесь тоже не удается добить-
ся строгого упорядочения, следует считаться с тем, что любое упо-
рядочение решений, как правило, лучше, чем отсутствие порядка
вообще. Дополнительная дисциплина, которую упорядочение при-
вносит в процесс проектирования, помогает предотвратить отклады-
вание решений на слишком поздний срок.
Как было сказано в гл. 1, основные цели операционной системы
состоят в том, чтобы, во-первых, обеспечить пользователей удобны-
ми средствами и, во-вторых, предоставить эффективный метод сов-
местного использования ресурсов системы. Следовательно, то, с
чем на самом деле сталкивается пользователь, есть виртуальная
машина, чьи характеристики больше напоминают характеристики
операционной системы, чем основного аппаратного оборудования.
Операционная система наводит мост через пропасть между вирту-
альной машиной пользователя и реальной аппаратурой машины.
Рассматривая операционную систему в таком плане, ее разработ-
чики могут идти по меньшей мере двумя путями: от аппаратуры
вверх, к- виртуальной машине пользователя; или от виртуальной
машины пользователя вниз, к реальному аппаратному оборудова-
нию. Как было сказано выше, более гибкая виртуальная машина,
ориентированная на пользователя, традиционно рассматривается
как более «высокая», чем основная машина. Сформулированные два
подхода к проектированию будем называть далее соответственно ме-
тодами «снизу вверх» и «сверху вниз».
8.2.2. Метод проектирования „снизу вверх*
Применяя метод проектирования «снизу вверх», разработчик
начинает с основного аппаратного оборудования. «Чистая» аппара-
тура представляет собой довольно неудобную машину, чтобы ре-
шать на ней задачи. Поэтому разработчик добавляет к машине слой
программного обеспечения. Программное обеспечение вместе с ни-
жележащей аппаратурой обеспечивает выполнение некоторого мно-
жества команд, определяющих новую виртуальную машину. На сле-
дующем шаге выделяется другое нужное свойство, добавляется но-
вый слой программного обеспечения и получается еще более удоб-
ная виртуальная машина. Слои программного обеспечения добав-
ляются последовательно, причем каждый слой реализует одно или
несколько желаемых свойств, до тех пор, пока наконец не будет
получена виртуальная машина, которая нужна пользователям. Это
основная схема метода проектирования «снизу вверх».
Некоторый слой программного обеспечения вместе с нижележа-
щими слоями программного обеспечения и аппаратурой определяет
некоторую виртуальную машину. Помимо средств, реализуемых
данным слоем программного обеспечения, эта новая виртуальная
машина может обеспечить либо все средства, предоставляемые вир-
туальными машинами более низких уровней, либо только некоторые
из этих средств, либо вовсе ни одного из них. Например, базисная
система управления файлами, описанная в гл. 6, использует систему
ввода-вывода и, конечно, аппаратное оборудование. Команды, вы-
полняемые системой ввода-вывода и аппаратурой, определяют не-
которую виртуальную машину. Очевидно, пользователю базисной
системы управления файлами дается право обращаться к этим коман-
дам, выполняемым упомянутой виртуальной машиной. Однако,
имеет ли пользователь автоматический доступ и к виртуальным ма-
шинам более низкого уровня, чем базисная система управления
файлами, а именно к системе ввода-вывода, определяется на этапе
проектирования. Соответствующее решение может быть предостав-
лено самой базисной системе управления файлами. Другими слова-
ми, базисная система управления файлами обеспечивает выполнение
своих собственных команд плюс некоторые команды виртуальных
машин более низкого уровня по своему усмотрению. Другой способ
состоит в следующем: структура системы может быть определена та-
ким образом, что пользователь какой-либо виртуальной машины ав-
томатически получает в свое распоряжение все команды виртуаль-
ных машин нижних уровней. Эту проблему можно лучше понять,
рассмотрев общий случай.
Пусть L (1), L (2), ..., L (и) — последовательность слоев програм-
много обеспечения, причем L(0) — аппаратура, а Л(1) — первый
слой программного обеспечения и т. д. Рассмотрим вариант, когда
слой L (0 может иметь доступ только к средствам виртуальной ма-
шины, определяемой слоем L(i—1). Если слою L(i) требуется ка-
кое-либо средство слоя L(i—2), то слой L(i—1) должен также пре-
доставлять это средство. Рассмотрим теперь другой вариант, когда
слой L (0 может использовать все средства, предоставляемые слоями
jL(l), L(2), ..., L(i— 1). Таким образом, виртуальная машина, опре-
деляемая слоем L (0, включает все команды до слоя L (0 и команды,
реализуемые самим слоем L(i). Промежуточными между этими дву-
мя вариантами являются такие варианты, когда слою L (0 разреше-
но использовать только некоторые из команд, обеспечиваемых слоя-
ми L(1),L(2), —1). В некоторых системах, например, первый
слой является единственным слоем, который может выдавать при-
вилегированные команды аппаратному оборудованию. Другие слои
могут выполнять непривилегированные команды плюс команды
первого слоя.
Каждый вариант имеет свои преимущества и недостатки. Если
слой имеет доступ к командам только одного слоя на предыдущем
уровне, разработчик каждого слоя должен иметь в виду только
предыдущий слой. Таким образом, релевантные характеристики
системы разделяются автоматически. В том случае, когда доступ-
ны все внутренние слои, разработчик следующего слоя должен тща-
тельно отобрать те команды, которые ему нужны как основные опе-
рации. Хотя с точки зрения проектирования первый вариант ка-
жется более привлекательным, он может оказаться очень неэффек-
тивным. Например, если некоторое средство, предоставляемое слоем
Л(1), требуется в слое L(0, то каждый из слоев L(2), L(3), ...,
L(i—1) должен обеспечить это средство. Это означает, что запрос
данного средства слоем L (0 должен «просачиваться» вниз через
i—1 слой программного обеспечения, пока он не достигнет слоя
L(l), который способен выполнить запрос. Эти трудности, связан-
ные с проблемой эффективности, могут склонить к принятию второй
структуры.
Промежуточный вариант можно построить, введя древовидную
структуру слоев программного обеспечения. Каждый слой может
иметь доступ только к тем слоям, которые соответствуют его пред-
шественникам по дереву (см., например, рис. 2.1). Дерево частей
программного обеспечения представляет собой на самом деле дерево
виртуальных машин. Каждая виртуальная машина имеет все коман-
ды, обеспечиваемые ее предшественниками. Эта организация будет
описана подробнее в гл. 10, там, где будет идти речь о системе SUE.
При методе проектирования «снизу вверх» разработчик может
в каждый момент времени сосредоточить свое внимание на одном
уровне, проектируя только расширения текущей виртуальной ма-
шины верхнего уровня до новой виртуальной машины верхнего
уровня. В то же время и проектные решения принимаются в том
порядке, который соответствует порядку виртуальных машин. Сна-
чала принимаются решения относительно механизмов самых близ-
ких к аппаратуре, затем — о частях системы, более удаленных от
аппаратуры. В качестве примера системы, спроектированной по
уровням указанным способом, будет рассмотрена система THE
[Дейкстра, 1968 Ы.
8.2.3. Мультипрограммная система THE
Система THE — это мультипрограммная система, которая состо-
ит из семейства совместно выполняющихся последовательных про-
цессов и имеет страничную организацию памяти. Каждому пользо-
вателю и каждому периферийному устройству ввода и вывода (для
буферизации) соответствует один последовательный процесс; с ба-
рабаном связан процесс «управление сегментами», который пере-
сылает страницы между основной памятью и барабаном;с клавиату-
рой оператора связан процесс «интерпретация сообщений». Струк-
тура системы имеет шесть уровней виртуальных машин.
На нулевом уровне процессор; обслуживает процессы, которые
не могут быть заблокированы. На этом уровне для процессов, тре-
бующих квантования времени, обрабатываются прерывания от ча-
сов реального времени. Выше этого уровня каждый процесс имеет
свой собственный виртуальный процессор. Другими словами, про-
цессы возникают и выполняются независимо, как если бы каждый
из них имел свое процессорное устройство.
Процесс «управление сегментами» находится на 1-м уровне и
выполняет обмен страницами между памятью и барабаном. Выше
этого уровня существует концептуальная одноуровневая память.
Другими словами, исчезает различие между страницами на бараба-
не и в оперативной памяти.
Процесс «интерпретация сообщений» находится на 2-м уровне.
Клавиатура консоли используется всеми процессами. При посылке
сообщения оператору процесс должен указать свое имя. Аналогич-
но, когда оператор посылает сообщение, он должен указать процесс,
которому должно быть передано сообщение. Обязанность процесса
«интерпретация сообщений» состоит в том, чтобы доставить каждое
сообщение соответствующему процессу. Можно считать, что каж-
дый процесс, расположенный выше этого уровня, имеет свою собст-
венную клавиатуру консоли. Заметим, что, если бы процесс «ин-
терпретация сообщений» был помещен на более низкий уровень,
чем процесс «управление сегментами», потребовалось бы резерви-
ровать постоянную область оперативной памяти для интерпретации
сообщений, так как нижележащая виртуальная машина не обеспе-
чивала бы страничный обмен.
3-й уровень состоит из процессов, выполняющих буферизацию
потоков ввода и вывода для периферийных устройств. Выше этого
уровня процессы работают с логическими устройствами. Процессы
ввода-вывода должны быть на более высоком уровне, чем процесс
«интерпретация сообщений», потому что они должны иметь возмож-
ность связываться с оператором (например, чтобы сигнализировать
о сбоях оборудования).
Пользовательские процессы находятся на 4-м уровне, процесс
оператора — на 5-м уровне.
Основные преимущества метода проектирования «снизу вверх»
вытекают из способа структурирования, ограничивающего построе-
ние системы. Между различными уровнями можно организовать
четкий интерфейс; при этом, поскольку любой процесс может тре-
бовать обслуживания только от процесса на более низком уровне,
исключаются всякие непредвиденные зацикливания. Метод разра-
ботки «снизу вверх» может быть применен также к реализации сис-
темы. Уровни могут реализовываться в соответствии с их порядком,
начиная с аппаратуры и далее вверх. Каждый уровень реализации
определяет новую виртуальную машину, которую можно постро-
ить и затем проверить. Тестовые процедуры, использующие этот
метод, могут быть более исчерпывающими, так как каждый уровень
можно проверять по отдельности и достаточно полным образом.
Когда некоторый уровень проверен до конца, можно добавлять
части следующего уровня и продолжать проверку. Такое иерархи-
ческое построение системы дает проектировщику большую уверен-
ность в правильности данной системы.
Нетрудно догадаться, что главная трудность в применении этого
метода проектирования заключается в выборе уровней и иерархи-
ческом упорядочивании. Видно, что в системе THE уровень харак-
теризуется распределением ограниченного ресурса для процессов
более высоких уровней. Если применяется структура процессов
типа «отец — сын», ее можно связать и со структурой самого про-
ектирования системы по уровням (см. также разд. 2.3). В системе
SUE дерево процессов типа «отец — сын» прямо связано с иерархи-
ческой структурой, используемой при проектировании.
8.2.4. Метод проектирования „сверху вниз*
Альтернативный способ проектирования системы состоит в том,
что исходят из желаемых свойств виртуальной машины пользова-
теля и последовательно разрабатывают уточнения в направлении к
аппаратуре [Парнас и Дарринджер, 1967]. Разработчик вначале
определяет виртуальную машину пользователей. Реализация этой
виртуальной машины полностью не специфицируется. Неопределен-
ные части проектируются в дальнейшем как компоненты системы.
Эта работа продолжается до тех пор, пока система не определена
настолько, что ее основные функции реализуются аппаратурой или
модулями, непосредственно выполняемыми на аппаратуре, такими,
например, как программы на языке АЛГОЛ.
Рассмотрим снова аналогию с проектированием моста. Мост
можно спроектировать, исходя просто из описания его функцио-
нального назначения. Он должен перекрыть определенное расстоя-
ние, выдержать определенную нагрузку транспортных средств и
т. д. Отсюда можно вывести требования к отдельным частям, на-
пример длину, ширину и прочность платформы, высоту опор и на-
грузку на них. Каждая часть может затем проектироваться в соот-
ветствии со своими спецификациями (например, отдельно платформа,
структура и покрытие). Проектирование моста не обязательно ве-
дется в том же порядке, что и строительство моста. На практике
этапы строительства моста диктуются законами физики. Во время
проектирования можно начертить платформу без опор. А на самом
деле платформы не могут быть подвешены в воздухе без соответ-
ствующих опор. Физические законы, которые налагают ограниче-
ния на строительство моста, не мешают испытывать промежуточ-
ные этапы проекта, например, с помощью построения моделей моста
и проверки на них общих свойств проекта в целом.
В результате проектирования «сверху вниз» получается множест-
во вложенных друг в друга компонент. В каждом пункте проек-
та у разработчика имеется некоторая абстракция функционального
описания некоторой компоненты, и он должен уточнить эту абст-
ракцию, разбив ее на более мелкие и более подробно проработанные
части. Предположим, например, что некто проектирует систему
способом «сверху вниз»; он должен был бы начать с множества
взаимодействующих процессов, которые обеспечивают необходи-
мые в системе средства. Процедуры и структуры данных будут оп-
ределены на более низком уровне абстракции. Каждая процедура
и структура данных уточняется в свою очередь, когда проектиру-
ются их составные части. Проектирование по существу определи-
ется вложенной последовательностью абстракций, описанной в
разд. 8.2.
При таком подходе вопрос о том, как следует реализовать неко-
торую компоненту системы — с помощью аппаратуры, микропро-
граммой или через программное обеспечение,— не должен решаться
на ранних стадиях проектирования. Выбор должен основываться
на общей эффективности и частоте использования, а не на каком-
либо действительном различии в характере работы данных компо-
нент.
Для проверки проекта в процессе его разработки можно с са-
мого начала применять моделирование [Цурхер и Ренделл, 1969].
Этот подход побуждает разработчика думать о том, какие функции
должна выполнять некоторая компонента, а не как данная компо-
нента будет их реализовывать. Компоненты системы можно модели-
ровать более детально, по мере того как продвигается работа по
проекту. Первоначальное представление какой-либо компоненты
есть алгоритм, который для данного входа вырабатывает с некото-
рой временной задержкой соответствующий выход и моделирует
работу данной компоненты. По мере продвижения работ по проек-
тированию данный алгоритм замещается последовательным набором
обращений к следующему множеству проектируемых компонент.
На каждой стадии разработок проект можно оценить, чтобы прове-
рить, продолжает ли он соответствовать поставленным целям [Гре-
хем и др., 1971; Парнас и Дарринджер, 1967]. Каждая абстракция
системы соответствует некоторой программе моделирования, кото-
рая построена из иерархии процедур. Эта программа определяет,
как нужно действовать с теми переменными, которые влияют на
состояние системы на этом уровне абстракции. Программа, назовем
ее Р, соответствующая некоторому данному уровню абстракции,
управляется программой более высокого уровня абстракции, кото-
рую назовем Q. Программа Q принимает более глобальные решения,
основываясь на значениях ее собственных переменных, которые на
самом деле являются абстракциями переменных программы Р.
Изменения в переменных программы Q соответствуют изменениям
в переменных программы Р. Аналогично некоторые процедуры про-
граммы Р делают запросы на выполнение работ к программам бо-
лее низких уровней абстракции.
Когда система окончательно спроектирована, ее можно реали-
зовать путем замены основных алгоритмов на самом низком уровне
абстракции и средств, обеспечиваемых программой моделирования,
теми элементами, из которых должна быть построена система. Если
эта замена сделана правильно, полученная система будет предостав-
лять в точности те средства, которые определены на самом высоком
уровне абстракции.
Заключительный интерфейс, когда программа моделирования
становится системой, может оказаться самым трудным. Каждое
уточнение системы производилось с явным стремлением к элегант-
ности, простоте и доступности для понимания. Абстракции низкого
уровня должны будут иметь дело с реальным оборудованием, кото-
рое часто громоздко. В результате заключительный интерфейс с
аппаратурой может оказаться не очень гладким.
Рассмотрим, например, защиту оперативной памяти. На неко-
тором высоком уровне абстракции разработчик в целях защиты мо-
жет разделить память на блоки переменной длины, соответствующие
сегментам. Если система реализуется на аппаратуре системы
IBM/360, то на более низком уровне абстракции защита может быть
реализована только блоками по 2 К байтов. Это деталь структуры
реальной машины, которую разработчик не может позволить себе
игнорировать в первоначальных абстракциях высокого уровня.
Любое уменьшение эффективности в заключительном интерфейсе
с аппаратурой может очень сильно повлиять на общую эффектив-
ность системы.
При использовании метода проектирования «сверху вниз» на-
блюдается тенденция локализации на уровнях последствий изме-
нений в системе. Тогда, если в проекте должно быть сделано какое-
то изменение, то нужно рассматривать только переменные соответ-
ствующего уровня и нет необходимости учитывать переменные более
низких уровней. Если нужно изменить один объект на определенном
уровне абстракции, то нужно переделать только ту часть системы,
на которую опирается данный объект. Остальная часть может ос-
таться без изменений. Если, например, некоторый модуль построен
из трех процессов А, В и С, то изменения в спецификациях для
процесса В повлияют только на дальнейшие уточнения процесса В.
Уточнения процессов А или С остаются неизменными.
Для подтверждения надежности и эффективности конструкции
системы можно использовать программу моделирования более вы-
соких уровней абстракции. В условиях такого тестового варианта
многие процедуры, к которым производится обращение, немедлен-
но возвращают управление, не выполняя никаких действий. Это
объясняется тем, что для таких процедур еще не разработаны коман-
ды и они не могут фактически выполняться. Проверка на этом уровне
тем не менее может подтвердить логическую корректность некото-
рых механизмов системы. Нужно внимательно следить за тем, чтобы
после «наполнения» процедур фактическими командами последние
строго соответствовали сделанным относительно них предположе-
ниям.
Другой путь состоит в том, что система может быть спроекти-
рована методом «сверху вниз», а реализована методом «снизу
вверх». Общий проект структуры выполняется «сверху вниз», но
модули фактически объединяются в систему по методу «снизу вверх».
При таком способе налицо все преимущества реализации методом
«снизу вверх» и в то же время не приносится в жертву возможность
общего охвата системы, предоставляемая методом проектирования
«сверху вниз».
Между сторонниками методов проектирования «снизу вверх»
и «сверху вниз» ведется много дискуссий. Многие полагают, что
проектирование «сверху вниз» больше соответствует идее проекти-
рования, по которой следует принимать более общие и важные ре-
шения на ранних стадиях и оставлять решения по детальной реали-
зации на более поздние этапы. Однако проектирование «сверху
вниз» требует лучшего осмысливания всей системы на ранней ста-
дии процесса проектирования. Проектирование «снизу вверх» мо-
жет требовать вначале менее полного осмысливания системы, так
как каждый слой программного обеспечения добавляется к уже
полностью определенной виртуальной машине. Вследствие этого
некоторые пропагандируют метод «сверху вниз», но на практике
проектируют системы методом «снизу вверх»; особенно это касается
операционных систем. Цель этого обсуждения заключается не в том,
чтобы прийти к выводу о преимуществе какого-либо подхода. Ос-
новная мысль этого раздела и фактически всей главы такова: про-
ектирование не должно осуществляться совершенно по-особому для
каждого отдельного случая. Тот факт, что способы проектирования
сравниваются по своим техническим качествам, уже обнадеживает.
Это дает основание считать, что проектирование программного
обеспечения может стать ближе к сфере науки, чем искусства.
8.2.5. Заключительные замечания
по структурному проектированию
Имеются и другие способы структурной организации в приня-
тии решений при проектировании. Проектирование не должно быть
строго связано с иерархией виртуальных машин, которые наводят
мост через пропасть между существующим оборудованием и вирту-
альной машиной пользователя. Хорошим примером служит прин-
цип «принимай сначала нетрудные решения». Это значит, что все
решения, которые не слишком сильно влияют на характеристики
системы, должны приниматься как можно раньше. Разумеется,
не всегда легко определить, какое решение не будет иметь важных
последствий. Если какое-либо важное решение будет принято не-
брежно, то может возникнуть грубая ошибка, которая повлияет
на эффективность системы в целом. Противоположный подход сос-
тоит в том, чтобы сосредоточить внимание на той части системы,
относительно которой есть сомнения. Если сначала разобраться
с трудным модулем, можно накопить знания, которые будут иметь
ценность и при формальном использовании методов «снизу вверх»
или «сверху вниз».
Иногда некоторый слой программного обеспечения системы яв-
ляется настолько важным, что он полностью проектируется вна-
чале. Один такой слой — это виртуальная машина, обеспечиваю-
щая все основные функции распределения ресурсов, называемая
обычно ядром операционной системы [Бринч Хансен, 1970]. Основ-
ными задачами ядра является реализация процессов и их механиз-
мов связи и обеспечение некоторых основных функций по органи-
зации совместного использования оборудования. Так, например, в
системе SUE (см. гл. 10) имеется небольшая часть, называемая
стержнем, которая обеспечивает простейшие средства по управле-
нию процессами, оперативной памятью и возможности защиты.
Ядро системы SUE реализует виртуальную машину, в которой име-
ется система ввода-вывода, базисная система управления файлами
и управление ресурсами. Стержень и ядро реализуют некоторую
фиксированную вспомогательную виртуальную машину, которая
направляет и ограничивает проектирование остальной части опера-
ционной системы.
Как правило, в проектировании ради практичности жертвуют
элегантными методическими указаниями. Иногда на более низком
уровне приходится использовать операцию, имеющуюся в вирту-
альной машине более высокого уровня; тем самым, очевидно, нару-
шается иерархия системы. Пусть, например, в системе, спроекти-
рованной по уровням виртуальных машин, неудобно хранить в опе-
ративной памяти все программы обработки отказов аппаратуры,
так как они занимают слишком много места. Если эти программы
хранятся на периферийном устройстве, то при возникновении сбоя
соответствующая программа должна быть вызвана в оперативную
память. Для выполнения этой операции полезна система управле-
ния файлами. Однако сбой обнаруживается обычно системой ввода-
вывода, которая представляет собой виртуальную машину более
низкого уровня, чем система управления файлами. Следовательно,
система ввода-вывода должна просить обслуживания от виртуаль-
ной машины выше нее, а именно от системы управления файлами.
То, что структурное проектирование иногда трудно применить,
не означает, что оно является неподходящим средством. Структур-
ное проектирование — это инструмент для организации процесса
проектирования. В особых случаях, однако, разработчик на свой
собственный риск может принять решение слегка отойти от техники
структурирования, если имеет для этого достаточно оснований.
8.3. Подход к проектированию
Основываясь на изложенных выше методах и некоторых общих
принципах проектирования, опишем в общих чертах проектирова-
ние программного обеспечения, составляющего операционную сис-
тему. В качестве основного предположения примем, что дано опи-
сание функций системы и дано оборудование или по крайней мере
полная спецификация оборудования. Проектирование разбивается
на пять этапов. Выделение различных этапов не имеет принципи-
ального значения. Разделение на этапы сделано лишь для того,
чтобы обеспечить дополнительную дисциплину процееса проекти-
рования. Хотя этапы выполняются последовательно, часто бывают
необходимы возвращения к предыдущим этапам. Во время проек-
тирования решения принимаются с некоторой степенью неуверен-
ности. Они не могут быть всегда правильными. Следовательно, раз-
работчику, может быть, придется повторить некоторые этапы не-
сколько раз.
1. Эскизный проект. В качестве первого приближенного описа-
ния различных модулей и их интерфейса должен быть сформулиро-
ван общий эскизный проект системы. Мостом через пропасть между
функциональным описанием системы и возможностями аппаратуры
служит структурированный набор модулей. Проектирование осу-
ществляется по методу «сверху вниз», как описано в разд. 8.2.4.
Некоторые виртуальные машины могут быть определены заранее,
как, например, ядро системы. Корректность промежуточных абст-
ракций системы проверяется при помощи моделирования или, по
крайней мере, путем очень внимательного изучения их описа-
ний.
2. Спецификация модулей и интерфейсов. На этом этапе точно
специфицируются модули и их интерфейсы, описанные на преды-
дущем этапе. Каждый модуль определяется сначала на высоком
уровне абстракции. Описания уточняются «сверху вниз» с целью
более подробной спецификации каждого модуля. В конце концов
все модули и интерфейсы оказываются описанными при помощи
детализированной абстракции. Это описание дает возможность под-
робно исследовать поведение компонент системы. На этом уровне
могут быть выявлены некоторые из логических проблем системы,
например возможности возникновения тупиковых ситуаций.
3. Проект общих механизмов. Теперь уже достаточно известен
общий замысел системы, и можно детально описать основные меха-
низмы для решения следующих проблем: а) реализации процессов,
Ь) связи между процессами, с) защиты, d) распределения памяти.
Может возникнуть необходимость возвращения назад, к преды-
дущим этапам. Если принять некоторые ограничения на взаимо-
действие между различными модулями, можно улучшить какой-
либо конкретный механизм. Так, например, предположение об
иерархической организации процессов упрощает механизм связи
между процессами.
4. Общее проектирование модулей. Каждый модуль в системе
может теперь проектироваться отдельно. Модуль может быть по-
делен на некоторое число процессов и/или процедур, взаимодействие
между которыми должно быть точно определено. Для каждого вы-
зова модуля должны быть точно установлены схема выполнения и
параметры, используемые в модуле.
К данному моменту уже имеется достаточно подробная картина
системы, которая позволяет оценить ее общую эффективность.
При помощи несложных подсчетов можно вычислить время, тре-
буемое на определенные частые операции, которые будут в значи-
тельной степени определять производительность системы. Возмож-
но, придется повторить предыдущие шаги, особенно если качество
системы не соответствует исходным спецификациям.
5. Детальное проектирование каждого модуля. Для каждого
модуля независимо составляется подробный проект и выполняется
программирование и проверка. Часто трудно разделить детальное
проектирование от самого программирования. В гл. 9 описывается
метод программирования «сверху вниз», который служит естест-
венным продолжением метода проектирования «сверху вниз».
Объединение модулей в системе можно вести способом «снизу
вверх», что позволяет применять тщательную проверку. Небрежный
проект может породить серьезные трудности на этапе проверки.
Хотя коллективы сотрудников часто работают параллельно, они
должны объединять модули в определенном порядке. Если один
из модулей будет не готов, то для объединения и проверки других
отдельных модулей может возникнуть необходимость в его ими-
тации.
Излишне говорить, что эта заключительная фаза очень важна.
Все проблемы, которые не были разрешены в свое время на преды-
дущих этапах, возникают здесь вновь. Возможно, придется много
раз повторить этапы общего проектирования, причем разработчик
время от времени будет возвращаться к исходным спецификациям.
Этих трудностей следует ожидать. На практике этапы проектиро-
вания редко выполняются в полностью определенном заранее по-
рядке «сверху вниз» или «снизу, вверх». Следует, однако, избегать
неоправданного повторения этапов, когда предыдущий вариант
проекта прямо не используется. К таким неоправданным повторе-
ниям могут привести постоянные модификации, предпринимаемые
для удовлетворения новых требований. Так, люди, ответственные за
сбыт, могут неоднократно изменять спецификацию системы. В ре-
зультате у разработчиков и программистов может возникнуть со-
вершенная путаница, что повлечет за собой значительные задержки
в реализации проекта.
Одна из серьезных опасностей при проектировании — это «сверх-
проектирование». Имеется соблазн включить в систему дополни-
тельные возможности, если кажется, что они не затруднят конечной
реализации. Более мудрый подход состоит в том, чтобы исключить
дополнительные возможности, пока они не нужны. Неоправдан-
ная общность заметно снижает производительность, а также уве-
личивает сложность реализации системы. Лучше, чтобы система
была спроектирована способной к расширению. Тогда обобщения и
дополнительные возможности могут быть подключены позднее.
Конъюнктурные соображения могут выдвинуть жесткие, нере-
альные требования, которые невозможно удовлетворить. В резуль-
тате при проектировании применяется много решений «для данного
случая». Полученная система может оказаться неспособной спра-
виться с противоречиями, порожденными «опрометчивым» проекти-
рованием. Хотя можно кое-как сделать прототип системы для де-
монстрации, по-видимому, впоследствии придется начинать все
проектирование сначала. Тщательное проектирование совершенно
необходимо, особенно в начальной фазе. Сколько бы ни делалось
заплат, они не могут улучшить плохо спроектированную систему.
Чтобы ускорить процесс проектирования, для реализации боль-
ших операционных систем обычно привлекают большое количество
людей. В работе над проектом принимает участие много недоста-
точно подготовленных людей. Организация связи между людьми
и между проектируемыми ими модулями становится проблемой.
Наиболее одаренные участники растрачивают большую часть своих
способностей на руководство проектом. Эти замечания естественно
подводят нас к вопросам руководства проектом.
8.4. Руководство проектом
Производство программного обеспечения обычно не укладывает-
ся в рамки первоначальных оценок по его стоимости и времени
создания, и это, возможно, еще слишком мягко сказано. Как по-
казал опыт, значительные задержки и превышение стоимости встре-
чаются настолько часто, что в производстве программного обеспе-
чения с ними считаются как с реальным фактом. Для учета возмож-
ного плохого руководства и неопределенных факторов, влияющих
на проект, всегда можно умножить время, взятое по предваритель-
ной оценке, на некоторый большой, взятый с запасом, коэффициент.
Однако такой подход вряд ли можно считать хорошим.
Источники трудностей в руководстве проектами программного
обеспечения можно разделить на две категории в соответствии с
двумя видами плохой организации.
1. Плохое руководство. В силу того что между образованием в
области вычислительной науки и в сфере управления имеется боль-
шой разрыв, очень мало людей обладают достаточной квалификаци-
ей и в науке, и в управлении. Вследствие этого проектами програм-
много обеспечения руководят или хорошие технические работники
с ограниченными способностями в области руководства, или опыт-
ные руководители, которые на самом деле не понимают проекти-
руемой системы и с трудом находят общий язык с разработчиками
программного обеспечения.
2. Беспорядочная деятельность. При производстве программного
обеспечения очень трудно вести правильное планирование. Специ-
фикации изготавливаемой системы подвергаются модификациям.
Изменения персонального состава бывают частыми и болезненными.
Запланированных технических средств и данных оказывается не-
достаточно. Для руководства проектами программного обеспечения
нужно использовать специальные методики, которые учитывают
характер проекта. Например, нужно представлять с самого начала,
что конечный результат будет существенно отличаться от предпо-
лагаемого.
Работа над проектом программного обеспечения иногда прохо-
дит в такой обстановке, что покажется любому руководителю кош-
маром. Действительно, когда специалист по мостам успешно спро-
ектирует мост, он обычно продолжает заниматься тем же делом и
проектирует другой мост. А когда специалист по программному
обеспечению успешно завершает проектирование какой-либо систе-
мы программного обеспечения, его обычно переводят на другую,
более сложную систему, или на руководящий пост, или на научную
работу. Следовательно, большинство участников работы над про-
ектом — новички в проектном деле, и они обучаются по мере вы-
полнения полезной работы.
Общая цель руководства проектом заключается в том, чтобы
получить желаемую систему в соответствии с установленными кри-
териями проектирования, спецификациями и доступными ресурса-
ми. Начальная задача — определить общий диалект естественного
языка для общения. К сожалению, в сфере программного обеспе-
чения термины не всегда означают для всех одно и то же. Может
оказаться полезным выбрать легкое для понимания (!) руководство
по какой-либо существующей системе в качестве предварительного
словаря терминов. Участники проекта могут использовать это ру-
ководство как базу для устного и письменного общения в течение
всей работы над проектом.
Важна правильная документация по проекту. Полезно иметь
рабочий журнал проекта. Каждый участник работы должен вести
копию журнала, которую он обязан регулярно обновлять. Основ-
ные решения, рабочие документы, технические отчеты, протоколы
заседаний — все, что считается важным для проекта, должно за-
писываться в рабочий журнал. (Один член рабочего коллектива
может быть ответственным за внесение новых данных в журнал.)
Материал можно периодически перерабатывать в более сжатую
форму. Старые версии могут переходить в специальный раздел в
конце журнала. Рабочий журнал должен не только отражать теку-
щее состояние проекта, нои давать полную историю работы над
проектом. Таким образом, рабочий журнал может служить основой
для хорошей документации. Он поможет также сделать «посмерт-
ное» изучение проекта после его завершения или в случае его
внезапного прекращения.
На контрольных этапах проекта следует тщательно составлять
соответствующие отчеты. Отчеты по контрольным этапам не долж-
ны рассматриваться как бремя для проекта; они должны выявить
некоторые действительные достижения и обеспечить обратную
связь. Каждый отчет по контрольному этапу должен всегда учиты-
вать исходные цели, спецификации и выгоды данного проекта.
Если возникает необходимость внести предложение по изменению
начальных установок, то, перед тем как продолжить работу по
проектированию, это предложение должно быть письменно сфор-
мулировано.
Если рабочий коллектив — небольшой (от пяти до семи человек,
так что они могут собираться за одним столом за завтраком), то
собирать всех членов группы желательно два-три раза в неделю.
Одно совещание может носить скорее технический характер, а дру-
гое — неформальный. Следует поощрять частые неформальные
беседы. Парнас полагает, что слишком тесное общение между чле-
нами группы может отрицательно сказаться на модульности [Пар-
нас, 1971], поскольку люди будут тяготеть к использованию нефор-
мальной информации в обход стандартных интерфейсов. Преодоле-
ние этой трудности — вопрос руководства и дисциплины.
Если рабочий коллектив не очень мал, неформальное общение
почти невозможно. В отношении проекта должны возникать такие
вопросы, как, например: почему он такой большой? Нельзя ли его
сделать меньше? Следует использовать обычные средства связи
(такие, как рабочие записки), но нужно отдавать себе отчет, что на
организацию связи может потребоваться значительная часть всех
усилий, затрачиваемых на проект.
Некоторые существующие системы были спроектированы «боль-
шими» коллективами людей. Под «большим» проектом программно-
го обеспечения обычно понимают такой, над которым работает более
25 исполнителей с двумя, по меньшей мере, уровнями руководства.
Проблемы руководства большими проектами были описаны в двух
отчетах НАТО по разработке программного обеспечения [Наур и
Ренделл, 1969; Бакстон и Ренделл, 19701. В них прослеживается
тенденция отрицать необходимость больших проектов программного
обеспечения. Вместо того чтобы нанимать огромное число неопыт-
ных людей, нескольким высоко квалифицированным специалистам
предоставляют все необходимые технические средства для выполне-
ния проекта. На первый взгляд, чем больше людей занимаются
проектом, тем больше производительность и выше коллективные
научные достижения; однако производительность в конце концов
достигает некоторого максимума. Положение точки, с которой на-
чинается уменьшение производительности, зависит от качества ру-
ководства проектом. Одна из причин меньшей производительности
в больших проектах состоит в том, что для коллективов свыше пяти-
семи человек требуется формальная структура управления. В боль-
ших проектах программного обеспечения нужны руководители,
которые «высококвалифицированны, легко сходятся с людьми, тер-
пимы, хорошо информированы, исключительно тактичны, но, к
сожалению, весьма редки» [Наур и Ренделл, 1969]. Такие люди
существуют, но было бы заблуждением считать, что их всегда можно
привлечь для руководства проектом.
В соответствии с «законом Конвея», структура любой системы
похожа на структуру организации, которая ее изготавливает [Кон-
вей, 1968]. Качество взаимодействия между различными функци-
ональными модулями системы будет таким же, как и качество взаи-
модействия между коллективами, которые работали над модулями.
При небольших коллективах между разработчиками существует
хорошая связь, и они участвуют в проектировании нескольких
функциональных модулей. Эта ситуация имеет очевидные преиму-
щества. Здесь должен быть по меньшей мере один главный разра-
ботчик (лучше два), который охватывает весь проект. Этот человек
не может быть руководителем проекта, так как руководитель не
может одновременно руководить проектом и контролировать все
детали проекта. Главный разработчик системы должен быть осво-
божден от отнимающих время второстепенных задач, чтобы он мог
посвятить большую часть своего времени оценке идей других раз-
работчиков. В небольших проектах члены коллектива принимают
участие в проектировании нескольких модулей, и они начинают
разбираться в системе в целом. Они не предпринимают локальной
оптимизации, если очевидны ее отрицательные последствия для
системы в целом. Кроме того, они меньше нуждаются в формальных
уровнях управления. «Демократия» оправдывает себя в достаточно
малых группах.
Чтобы сохранить маленькой группу, работающую над проектом,
нужно создать соответствующую обстановку, которая способство-
вала бы повышению производительности каждого разработчика и
программиста. Большое внимание привлек один способ организа-
ции, который дает возможность разработчику рационально исполь-
зовать при проектировании свое ценное время. Этот способ называ-
ется методом «главного программиста» [Бейкер, 1972; Миллс, 1971].
Главная идея состоит в том, чтобы вернуть опытных и талантливых
людей от управления к фактическому проектированию и програм-
мированию. Главный программист вместе с программистом-дубле-
ром проектирует и пишет большую часть программ. Им помогает
программист, ведающий библиотекой, который выполняет всю тех-
ническую работу по обеспечению пропуска программ на машине,
обновлению руководств и т. д. Кроме того, в группе используются
несколько программистов, которые пишут небольшие отдельные
программы в соответствии со спецификациями и интерфейсом, за-
данными главным программистом. И наконец, завершают комплек-
тование группы руководитель и специалист по анализу систем.
Метод «главного программиста» подразумевает небольшую хоро-
шо организованную группу, в центре которой находится очень
квалифицированный программист, выполняющий большую часть
проектирования программ. Сами программы должны проектировать-
ся структурным способом «сверху вниз». Каждый член группы вы-
полняет вполне определенные функции. Программист, ведающий
библиотекой, собирает всю информацию о запусках и обновлениях;
таким образом, программы не являются более собственностью каж-
дого индивидуального программиста.
Метод «главного программиста», соединенный со структурным
программированием, был с замечательным успехом применен на
практике — в проекте информационной системы для газеты «Нью-
Йорк Таймс» [Бейкер, 1972]. Производительность труда в этой
группе была намного выше средней. Программы быстро начинали
правильно работать, чем сокращался очень дорогой период от-
ладки. Время, затраченное на организацию, планирование и тща-
тельное проектирование, окупилось на заключительных этапах реа-
лизации системы.
8.5. Заключительные замечания
В предыдущем разделе были обсуждены некоторые организаци-
онные проблемы, возникающие в проектах программного обеспече-
ния. Операционная система — результат тщательного проектиро-
вания и хорошей организации. Было кратко описано несколько
принципов и методов проектирования. Они не составляют какой-
либо строгой методологии проектирования. Напротив, точную мето-
дологию проектирования трудно вообразить. Проектирование —
это творческий процесс, который нельзя полностью контролировать
и стеснять правилами. Он не может быть алгоритмизирован, однако
он не должен быть совсем неуправляемым. Наверно, проектирова-
ние без ограничений так же сложно, как и при чрезмерных ограни-
чениях. Хороший вариант находится где-то посередине. Достиг-
нуть этой середины помогает структура. Разработчик в этом случае
еще обладает большой свободой, но все же руководствуется общей
структурой системы.
Одним из наиболее ценных ресурсов при разработке операцион-
ной системы или любой другой системы программного обеспечения
является время разработчика. Средства проектирования програм-
много обеспечения могут быть очень ценны с точки зрения увели-
чения эффективности труда разработчика. Однако в некоторых
проектах средства программного обеспечения или недоступны, или
плохо используются. Следовательно, разработчик должен больше
полагаться на свою собственную компетентность. К сожалению, ком-
петентность и способность к проектированию — дефицитные ресур-
сы. Во многих учреждениях исследовательская работа концентри-
руется на разработке средств проектирования, которые разгрузят
проектирование от некоторых непринципиальных трудностей. Про-
ект PEARL [Сноудон, 1972], проект LOGOS [Роуз, 1972], проект
ISDOS [Тейчроу и Сайани, 1971] и другие делают попытку создать
такие средства для проектирования, которые дали бы разработчи-
ку возможность описания, проверки и анализа проектируемой сис-
темы.
Задания
8.1. Определите меру связности между двумя модулями в системе
программного обеспечения. Можете ли вы использовать эту меру
для оценки сложности всей системы?
8.2. Обрисуйте в общих чертах последовательность виртуальных
машин, описывающую операционную систему вашей установки.
В каком отношении друг к другу находятся виртуальные машины?
Как бы вы описали виртуальную машину, связанную с каким-либо
данным языковым процессором, например с компилятором с языка
ФОРТРАН?
8.3. У разработчиков аппаратуры своя собственная методология
проектирования. Исследуйте их методы. Являются ли эти методы
структурными? Похожи ли они на методы проектирования програм-
много обеспечения?
8.4. В литературе предлагались системы автоматизации установле-
ния интерфейса [Вайсман и Стэйси, 1973]. Опишите кратко исполь-
зование монитора, введенного в гл. 2, для обеспечения в системе
стандартного интерфейса между модулями. Приведите примеры.
8.5. В большинстве технических дисциплин существуют справоч-
ники с большим числом сведений, накопленных из прошлого опы-
та, которые очень полезны для разработчика. Какой материал, по
вашему мнению, следует включить в справочник по разработке
программного обеспечения?
8.6. Рассмотрим систему, организованную в виде иерархии вирту-
альных машин. Приведите несколько примеров средств, обеспечи-
ваемых виртуальными машинами низкого уровня, которые вы бы
предпочли изъять из виртуальных машин более высоких уровней.
Как бы вы этого достигли? Можете взять в качестве основы различ-
ные уровни системы управления файлами.
8.7. Можете ли вы предложить другой способ расположения уров-
ней системы THE, описанной в разд. 8.2.3? Обоснуйте ваш ответ.
8.8. Анализ проектов по системе PERT стал первым средством уп-
равления во многих областях. Однако это средство проектирования
не используется широко в проектах программного обеспечения.
Почему?
8.9. Рассмотрим связь между иерархией процессов, описанной в
разд. 2.3, и иерархией виртуальных машин. Какова роль связи
между процессами? Возьмем систему SUE, описанную в гл. 10.
Как процессы и связь между ними относятся к виртуальным маши-
нам системы и их структуре?
8.10. Исследуйте свойства некоторых языков моделирования, на-
пример языков GPSS, Симула 67 и Simscript. Выберите язык, ко-
торый подходит для оценки системы во время проектирования.
Обоснуйте ваш выбор.
8.11. Проведите эксперимент по сравнению двух способов органи-
зации связи между процессами, например «почтовых ящиков» и
средств, имеющихся в системе SUE. Какие заключения вы можете
сделать, исходя из вашего опыта, относительно использования моде-
лирования на этапе проектирования?
8 № 1250
Глава 9
РЕАЛИЗАЦИЯ
9.1. Введение
Между фазами проектирования и реализации при разработке
системы программного обеспечения нельзя провести четкой грани-
цы. Если система разрабатывается с использованием структурных
методов, скажем «сверху вниз», то проектирование плавно и посте-
пенно переходит в конкретную реализацию. Единственное отличие
фазы реализации от фазы проектирования состоит, возможно, в том,
что для описания реализации системы используется некоторый
язык программирования вместо более абстрактных и неформальных
понятий, употребляемых на фазе проектирования. Однако, если
выбран подходящий, язык программирования, им можно восполь-
зоваться и на этапе проектирования для описания частей системы.
Вопросы проектирования и вопросы реализации обсуждаются в
разных главах только для того, чтобы подчеркнуть различные ас-
пекты и свойства системы программного обеспечения, полученной
в качестве конечного продукта.
Какие свойства желательны для системы программного обеспе-
чения и для любой программы? Система или программа должна быть,
по меньшей мере, надежной, эффективной и доступной для понима-
ния. Операционная система должна быть надежной; ненадежное
программное обеспечение почти бесполезно независимо от того,
сколько услуг оно призвано обеспечить. Для некоторых применений
цена ошибки значительно выше, чем стоимость вычислительной сис-
темы. Ненадежная система программного обеспечения может со-
держать, например, скрытые ошибки, которые могут привести к пор-
че данных системы или пользователя без каких-либо предупреждений
об этом. Ошибка может исказить данные, дублировать которые очень
дорого. Программное обеспечение должно проектироваться и реа-
лизовываться с учетом достижения надежности. Надежность не
должна быть предоставлена воле случая. Как заметил Ренделл, на-
дежность — не какое-то второстепенное качество. Внутренне не-
стабильная, ненадежная система с трудом поддается улучшению.
При исправлении в ней ошибок часто неумышленно вносятся новые.
Операционная система должна быть эффективной. Поскольку
она подолгу занимает машину и требует много ресурсов, эффектив-
ность операционной системы может оказывать значительное влияние
на общую производительность вычислительной системы. Однако
различные части системы по-разному влияют на общую эффек-
тивность системы. Действительно, замечено, что только очень
небольшая часть операционной системы ответственна за использо-
вание большей части процессорного времени. Следовательно, для
одних частей системы требования обеспечения эффективности более
важны, чем для других.
Факторы удобства часто преобладают над соображениями эф-
фективности. Дополнительные мощность и скорость машин, обес-
печиваемые в результате технических новшеств, часто использу-
ются для создания более удобных машин, а не для увеличения объе-
ма реальной работы, выполняемой машинами. Соображения надеж-
ности также иногда берут верх над эффективностью. Тем не менее
существует много приложений, таких, как системы реального вре-
мени или системы управления процессами, где скорость ответа яв-
ляется критической. Относительная важность таких факторов, как
надежность, эффективность и удобство, должна зависеть от типа
обслуживания, предоставляемого системой.
Доступность операционной системы для понимания исключи-
тельно важна. Программы пишутся не только для выполнения их
на машинах, но и для того, чтобы их могли понимать другие люди.
Операционные системы непрерывно развиваются; постоянно вво-
дятся новые возможности. Кроме того, эксплуатация систем требу-
ет обширной и подробной документации. Если программы будут
обладать «приятными» свойствами, облегчающими их восприятие,
то составление документации системы упростится. Программы
должны быть, например, продуманно разбиты на части, иметь хо-
рошие комментарии, в них должны быть использованы мнемониче-
ские имена переменных.
Надежную, эффективную и доступную для понимания операци-
онную систему сделать нелегко. Для обеспечения таких характе-
ристик необходимы целенаправленные и иногда мучительные уси-
лия. Поскольку за реализацию отвечает программист, выбранные им
средства программирования заставляют следовать определенной
дисциплине. Очевидно, основное средство программистов — это
язык программирования. Язык оказывает влияние на стиль програм-
мирования и тем самым на свойства программ. Следовательно, выбор
языка программирования — одно из первых решений, которое
должна принять группа реализации.
9.2. Выбор языка программирования
Как правило, раньше операционные системы писались на языке
ассемблера. Считалось, что при этом получаются программы более
эффективные, чем при использовании языков высокого уровня.
Имевшиеся языки программирования были в значительной степе-
ни ориентированы на научные и коммерческие приложения (напри-
мер, ФОРТРАН и КОБОЛ). Их свойства не особенно подходили для
системного программирования. В последнее время некоторые опе-
рационные системы были написаны на языках высокого уровня
(например, система MULTICS — на языке PL/I [Корбато, 19691)
и разработчики систем обнаружили много достоинств такого подхо-
да по сравнению с использованием языка ассемблера. Это обстоя-
тельство вызвало споры по поводу преимуществ использования язы-
ков высокого уровня для реализации систем [Сэммет, 1971].
Языки высокого уровня имеют структуру, которая может помочь
программисту писать лучшие программы. На языке высокого уровня
алгоритмы легче запрограммировать, так как программисту не надо
заботиться о деталях генерации программы на входе ассемблера,
учитывающей различные тонкости. Это также ускоряет реализацию,
потому что в принципе программист может написать одинаковое
количество отлаженных операторов на языке ассемблера и языке
высокого уровня за день. Однако главные преимущества сказыва-
ются не на этапе написания программ, а в основном на этапе их
осмысливания, проверки и отладки. В программах на языках высо-
кого уровня возможно самодокументирование, поэтому програм-
мисты могут легко воспринимать листинги разных программ. Это
особенно важно при эксплуатации программ.
Основной аргумент против использования языков высокого уров-
ня — возможное замедление выполнения программ. Однако анализ
частоты работы частей системы обычно показывает, что большую
часть времени в операционной системе работает только небольшое
число модулей. Таким образом, нет необходимости кодировать боль-
шинство модулей на языке ассемблера. Часто используемые модули,
как только они будут выявлены, можно переписать для обеспечения
большей эффективности. В системе MULTICS было достигнуто зна-
чительное увеличение скорости работы в результате написания не-
больших частей системы на языке ассемблера, таких, например,
как механизм смены страниц [Зальтцер и Джинтелл, 1970]. В целях
обеспечения удобства эксплуатации и документирования некоторые
из программ на ассемблере были позднее переписаны на языке вы-
сокого уровня (языке PL/I) с сохранением тех же характеристик по
скорости. Таким образом, улучшение достигается за счет дополни-
тельных усилий при реализации отдельных частей системы, а не
за счет использования языка ассемблера. Программы на ассемблере,
как правило, приводят к глобальной неэффективности, которая на-
много перевешивает локальную эффективность.
Если принять, что для реализации следует использовать язык
высокого уровня, то возникает вопрос: какой именно? Существует
много интересных языков, предназначенных для системного про-
граммирования, таких, как BCPL, PL/360, LIS, BLISS, LSD и SUE.
Более того, семья системных языков растете каждым годом, Некото*
рые языки высокого уровня общего назначения, такие, как PL/I
и PASCAL, также обладают подходящими свойствами. Хотя трудно
сделать объективный выбор в пользу одного конкретного языка,
можно выделить основные руководящие принципы такого выбора
[Атвуд и др., 1972].
Системный язык должен способствовать хорошему стилю про-
граммирования. Он должен быть удобным для написания компакт-
ных программ с легко обозримой управляющей структурой, под-
дающихся проверке на правильность. Структуры данных должны
быть гибкими, мощными и естественными. Употребление оператора
GO ТО подвергается большой критике из-за его слишком общей и
неконтролируемой природы [Дейкстра, 1968 с]. Он может быть ис-
пользован в программе во многих совершенно различных ситуаци-
ях, в некоторых случаях его употребление сильно снижает обозри-
мость программы.
Системный язык должен быть наглядным. Программы, написан-
ные на некоторых мощных языках, совершенно непостижимы для
всех, кроме программиста, который их написал. Применение мало-
понятных конструкций не должно поощряться языком. Больше
того, язык должен способствовать ясности выражения своими кон-
струкциями, правилами именования, возможностями для коммента-
риев и средствами разбиения на части.
Системный язык должен активно помогать в выявлении и лока-
лизации синтаксических и логических ошибок. Конструкции языка
не должны располагать к использованию двусмысленных и оши-
бочных построений. Кроме того, средства контроля, обеспечиваемые
за счет полезной избыточности языка, должны быть доступны как
во время компиляции, так и во время выполнения.
Системный язык должен быть пригоден для эффективной ком-
пиляции. Язык не может допускать использование мощных кон-
струкций, которые неизбежно порождают плохой код; он не может
иметь и ограничений, которые затрудняли бы программисту исполь-
зование «естественных» для машины конструкций. Несмотря на то
что программист не должен обычно беспокоиться об «идиосинкрази-
ях» машины, системный язык должен дать ему, если он пожелает,
точный контроль над порождением команд и распределением памя-
ти и регистров.
Язык оказывает громадное влияние на программы, которые пи-
шутся на нем. Обычно программисты не делают одинаковых оши-
бок на разных языках программирования. Некоторые конструкции
порождают ошибки чаще, чем другие. Такие ошибки в большей сте-
пени характеризуют язык, а не программиста. Причины характер-
ных ошибок могут быть связаны со сложностью конструкций, пло-
хими определениями, неестественным порядком выполнения и т. д.
Приведенные выше соображения могут помочь выявить такие ас-
пекты языков, которые затрудняют программирование систем,
CASE I OF
BEGIN
A;
в;
c >
ENO
Рис.9.1. Опера-
тор CASE языка
ALGOL W.
SPACE ЦВЕТ .’(КРАСНЫЙ, ЖЕЛТЫЙ, ЗЕЛЕНЫЙ);
TYPE ЦВЕТ СВЕТ;
CASE СВЕТ/ЦВЕТ OF
ЗЕЛЕНЫЙ: А ; .
КРАСНЫЙ: В;
ЖЕЛТЫЙ: С;
END
Рис. 9.2. Модифицированный оператор
CASE.
Рассмотрим, например, оператор CASE (ВАРИАНТ) в языке
ALGOL W, описанный Ихбиа и Риссеном J1971 ]. Оператор CASE
представлен на рис. 9.1, где действия А, В, С выполняются в соот-
ветствии со значением переменной I, равным 1, 2 или 3. Часто ошиб-
ки в операторе CASE связаны с пропусками или перестановкой
действий.
Теперь рассмотрим модифицированную версию конструкции
CASE на рис. 9.2, где множество меток ЦВЕТ содержит элементы
КРАСНЫЙ, ЖЕЛТЫЙ, ЗЕЛЕНЫЙ. Переменная СВЕТ имеет
тип ЦВЕТ, т. е. она может принимать только значения КРАСНЫЙ,
ЖЕЛТЫЙ или ЗЕЛЕНЫЙ. Действия выбираются по их меткам,
а не по номерам. Следовательно, они могут быть без труда перестав-
лены или одно из них опущено. В модифицированной версии опера-
тора CASE номера, относящиеся к вариантам действий, не должны
быть известны программисту. Номера устанавливает компилятор
независимо от программиста. Таким образом, модифицированный
оператор CASE устраняет проблемы, связанные с упорядочением
вариантов.
Кроме рассмотрения языковых конструкций, при выборе языка
следует также учитывать те компиляторы, которые для него разра-
ботаны. Компилятор должен обеспечивать разнообразный конт-
роль, особенно если язык допускает это. Компилятор должен вы-
лавливать по крайней мере большинство технических ошибок, та-
ких, как пропуск знаков пунктуации.
Рассмотрим, например, программу на языке ФОРТРАН на
рис. 9.3. [Элспас и др., 1971]. Программа синтаксически правильна,
но не имеет никакого смысла. Значение переменной Z изменяется,
в то время как предыдущее значение никак не было использовано.
Противоречие такого типа может быть обнаружено при компиляции.
Очевидно, компилятор не может обеспечить абсолютную надеж-
ность, поскольку часть семантической информации недоступна до
выполнения программы. Все же полезная избыточность в синтакси-
се языка может обеспечить компилятору возможность локализации
подозрительного места. Определенные ограничения, предусмотрен-
Z = простое арифметическое выражение
А1
А2
•
АМ
z = другое арифметическое выражение
Рис. 9.3. Пример программы. (Операторы 41,. . AN не ссылаются на перемен-
ную Z, не содержат команд ветвления, и к ним нет безусловных переходов по опе-
ратору GO ТО.)
ные в языке, предоставляют компилятору дополнительную инфор-
мацию, полезную для обнаружения ошибок. Однако введение в
язык ограничений и избыточности иногда не согласуется с идеей
использования в языке очень гибких и мощных языковых кон-
струкций.
К сожалению, поведение программ изучено недостаточно, осо-
бенно это касается типичных ошибок. Сами программисты не всегда
могут судить, что плохо в языке. Необходимы экспериментальные
данные относительно типа и частоты ошибок при использовании
различных языков программирования. Такая информация была бы
бесценна при выборе свойств языков, позволяющих писать хорошие
программы. Сделанные до настоящего времени оценки языков от-
носятся в основном к вопросам стиля и ясности. У разработчиков
языков очень мало сведений об использовании языков, на которые
можно опираться при проектировании языка.
Язык программирования — наиболее интенсивно используемое
средство на фазе реализации. Его свойства могут очень сильно по-
влиять на качество конечного продукта. Однако, подобно любому
другому средству, его необходимо правильно использовать. Это
естественно подводит нас к обсуждению вопроса о стиле программи-
рования.
9.3. Техника программирования
Имеется много способов оценки качества программы. Его мож-
но оценивать с точки зрения надежности программы, ее ясности,
удобства представления выходных результатов, использования па-
мяти, времени счета, простоты в эксплуатации и легкости внесения
изменений. В дополнение к оценке качества программы на фазе
реализации можно подсчитать усилия, затраченные на программи-
рование, такие, например, как время программирования; желатель-
но иметь оптимальным и этот показатель. Некоторые из свойств
программ, определяющих ее качества, совместимы друг с другом,
например доступность программы для понимания и удобство в эк-
сплуатации. Другие свойства противоречат друг другу, например
небольшое число операторов и время, затраченное на разработку.
На качество конечного продукта в значительной степени влияет
выбор желаемых качеств программы.
Эксперименты выявили большую разницу в результатах работы
различных групп программистов, разрабатывающих одну и ту же
программу, но преследующих различные цели [Вайнберг, 1971].
Сообщалось, например, что двум группам программистов Р («promt»,
т. е. «быстрая») и Е («efficient», т. е. «эффективная») дали одно
и то же задание с различными целями. Группа Р должна была как
можно быстрее написать работающую программу, а группа Е долж-
на была создать высокоэффективную программу (т. е. программу,
требующую мало процессорного времени). Группа Р оценила свои
потребности на разработку в 39 прогонов, а выполнила задание, ис-
пользовав 29 прогонов. Группа Е оценила свои потребности в 22 про-
гона, а использовала при отладке программы 69 прогонов. Обе
группы состояли из хороших программистов, примерно равных по
квалификации. Эксперимент показывает, что цели, поставленные
перед группой программирования, оказывают большое влияние на
ее работу и на ее оценку временных затрат. Приведенные выше за-
мечания, по-видимому, справедливы безотносительно к опыту и
квалификации программистов. Следовательно, цели программирова-
ния должны быть определены очень тщательно. К сожалению, в боль-
шинстве случаев цели не ставятся достаточно ясно и для конфликт-
ных ситуаций не определяются относительные веса различных ре-
шений. Поэтому группа программирования принимает произвольные
решения в отношении целей, что приводит к задержкам и дорогим
переделкам. В другом эксперименте результат программирования
одного и того же задания различными группами, преследующими
разные цели, отличался в пять раз в отношении объема памяти и
числа операторов [Вайнберг, 1971]. Примечательно, что все группы
достигли очень высоких результатов в соответствии с их индиви-
дуальными целями. Они сделали то, что от них требовалось. Это
не было различие между «хорошими» и «плохими» программистами,
а различие в выборе желаемых целей.
Квалификация самих программистов различна и зависит от их
образования, опыта и таланта. Широко распространено мнение, что
«хороший» программист может работать в 30 раз продуктивнее, чем
«плохой». Однако очень трудно описать в общих чертах, что должен
делать хороший программист. Принимая во внимание, сколько уже
сделано в программировании, удивляешься, как мало известно о том,
чем должно обусловливаться хорошее программирование. Цель
техники программирования состоит в том, чтобы дать возможность
средним программистам улучшить качество программирования за
счет использования самых подходящих средств и процедур.
В настоящее время проводится много экспериментов для выра-
ботки средств и принципов техники успешного программирования.
Одним из основных вкладов в этом направлении является идея струк-
турного программирования [Дейкстра, 1968 с; Дал и др., 1972;
Миллс, 1972]. Структурное программирование — это хорошо органи-
зованный способ построения программы «сверху вниз». Его не сле-
дует путать с программированием без оператора GO ТО. Можно на-
писать неструктурированную программу на каком-либо языке без
оператора GO ТО. С другой стороны, опытный программист может
написать хорошо структурированную программу на языке ассемб-
лера, например, используя соответствующим образом макро-
команды.
Далее в этой книге примем следующие определения:
1. Программирование без GO ТО — это программирование без
использования операторов GO ТО, например на языке, где нет опе-
ратора перехода GO ТО.
2. Структурное программирование — это высоко организован-
ный способ построения программы «сверху вниз». Описание про-
граммы последовательно уточняется, пока уровень абстракции не
станет уровнем языка программирования.
3. Структурированная программа — это программа, которая
ясна и понятна, что является результатом использования надле-
жащих управляющих операторов, правил разбиения на части и
имен переменных.
Структурированные программы обычно получаются с помощью
структурного программирования на языке с надлежащими свой-
ствами. Однако хорошие языковые характеристики, такие, на-
пример, как отсутствие операторов GO ТО, не гарантируют хо-
рошей программы. Рассмотрим, например, следующий фрагмент
на языке ФОРТРАН [Керниган и Плафер, 19731:
DO 10 Z-1, У
DO 10 J-I, N
10 V(Z, J) = (//J)^(J//)
В программе нет операторов GO ТО. Однако она не ясна, загадочни
и даже не эффективна. Функция программы состоит в генераци,
матрицы со всеми элементами, равными нулю, кроме диагонал ьнььх
которые полагаются равными единице. Для достижения данного
результата программа использует свойство усечения в операции
целого деления языка ФОРТРАН. Тот же самый результат может
быть получен с помощью менее хитроумной, но более наглядной
программы:
DO 20 / = 1, АГ
DO 10 J= 1, N
10 У(/, J)-0.0
20 V(/, /)-1.0
Структурированная программа в начале составляется из описания
общей функции программы на высоком уровне абстракции. Затем
все более и более подробно переопределяются процедуры и структу-
ры данных. Когда уровень детализации описания программы соот-
ветствует языку программирования, тогда программа готова. Дан-
ный подход иллюстрируется следующим примером [Миллс, 1971].
Назначение рассматриваемой программы — добавить раздел в биб-
лиотеку. Оно постепенно конкретизируется с помощью единичных
букв, служащих идентификаторами функций. Выражения, выделен-
ные курсивом, могут быть конкретизированы в виде основных опи-
саний какого-либо языка программирования.
Описания (уровень 0)
/ = добавить раздел в библиотеку
Функция f конкретизируется следующим образом: g THEN h (т. е.
сначала выполнить функцию g, а затем функцию ti)
Подчиненные описания (уровень 1)
g = откорректировать библиотечный индекс
h = добавить текст раздела к тексту библиотеки
Функция g конкретизируется следующим образом:
IF р THEN i ELSE j (т. e. если значение р истинно, то выполнить
функцию I, в противном случае выполнить функцию /)
Подчиненные описания (уровень 2)
р ~ имя раздела уже имеется в индексе
i = откорректировать указатель текста
j = добавить имя и указатель текста в индекс
После уточнения на двух уровнях имеем
f = (IF имя раздела уже имеется в индексе
THEN откорректировать указатель текста
ELSE добавить имя и указатель текста в ин-
декс)
THEN добавить текст раздела к тексту библиотеки
Абстракции функций, показанные выше в скобках, имеют су-
щественное значение для понимания описания программы на нижнем
уровне абстракции. На каждом уровне описания буквы, обозначаю-
щие функции, могут соответствовать отдельным операторам языка
программирования, процедурам, группе процедур или описанию на
естественном языке того, что делает данная функция. По мере по-
нижения уровня абстракции описания функций становятся более
детальными и все больше походят на понятия языка программиро-
вания. Больше того, так как на каждом уровне абстракции програм-
ма определена полностью, ее можно неоднократно в течение перио-
да разработки проверить вручную или даже промоделировать.
Структурированная программа — это довольно неопределенное
понятие, связываемое обычно с результатом структурного програм-
мирования. До некоторой степени, однако, структура структуриро-
ванной программы оценивается субъективно. Структура определяет-
ся с точки зрения человека, разбирающего программу; структуру
не всегда можно выявить. Структурное программирование позволяет
получать программу хорошо организованным способом. Структура
полученной программы может быть, а может и не быть легкодоступ-
ной неподготовленному читателю, если в программе не используются
макросредства. Такие приемы, как мнемоническое наименование
переменных, применение жестких правил деления на части, подчер-
кивающие структуру управления, и употребление комментариев
для объяснения сложных мест,— все это помогает «проявить» струк-
туру программы для более легкого ее обозрения.
В настоящее время придается большое значение легкости чте-
ния и удобству понимания программ [Вайнберг, 1971]. Чтение про-
грамм — очень интересное упражнение. Вайнберг отмечает пара-
доксальное явление, заключающееся в том, что программисты при
обучении обретают способность писать программы на языках про-
граммирования раньше, чем читать их, т. е. понимать программы на
данных языках [Вайнберг, 1971]. Как может программист рассчиты-
вать написать большие программы, если он не умеет их читать?
(Можно сравнить это с намерением человека, не умеющего читать
на естественном языке, написать стихи.) Структурированные про-
граммы читать, как правило, легче, чем неструктурированные. Как
указал Мак-Илрой, легко читаемая программа с большой вероят-
ностью будет и хорошо работать. Это не утверждение о связи причи-
ны и следствия; это просто наблюдение о том, что программы,
которые трудно понять, часто содержат скрытые ошибки, которые
не смог заметить программист. Такие ошибки встречаются гораздо
реже в тех случаях, когда действия программы можно легко понять.
Методы структурного программирования могут быть в равной
степени приложимы к проектированию структур данных [Дал
и др., 1972]. Структуры данных очень важны в операционных систе-
мах. Действительно, при проектировании и реализации операцион-
ной системы одновременно должны проектироваться структуры дан-
ных и программы. Иногда, в тех случаях, когда одними и теми же
структурами данных пользуются многие процессы, лучше начать
с проектирования структур данных, а не программ. Одним из приз-
наков правильного структурирования данных в программе может
служить, например, отсутствие указателей без ограничений. Такие
указатели аналогичны оператору GO ТО в том смысле, что по тексту
программы трудно предсказать истинный эффект от их использова-
ния. Лучше явным образом определить структуру данных и исполь-
зовать для получения данных соответствующие операции, такие,
как операции «затолкнуть» и «вытолкнуть» для стека.
Разработчики некоторых языков программирования для систем
отдают себе отчет в важности структур данных. Они создали много
средств для построения структур данных, как например, возмож-
ность определения программистом типов данных в языке PASCAL
[Вирт, 1971]. С помощью этих средств программист может опреде-
лить операции высокого уровня для работы со своими структурами
данных. Так, например, в некоторых языках программисту разре-
шено описывать такие структуры данных, которые в дальнейшем
могут быть реализованы с использованием процедур для основных
операций над ними.
Хотя структурное программирование может уменьшить скорость
написания программы на начальном этапе, оно чрезвычайно сокра-
щает время, необходимое на этапах отладки и апробирования про-
грамм [Бейкер, 1972]. При структурном программировании програм-
мисты обычно работают более продуктивно и программы, которые
они пишут, почти всегда лучше. Структурное программирование
помогает программисту получить общее представление о рассмат-
риваемой проблеме и глубокое понимание связей между различными
модулями. Полученную программу легче понять и описать;
даже ее правильность может быть легче установлена. Описание
структуры, налагаемой на программу в процессе ее проектирования,
обеспечивает возможность хорошей документации поведения
программы. Это значительно сокращает усилия по документации и
эксплуатации. Полученные недавно результаты подтвердили, что
указанный метод осуществим на практике [Бейкер, 1972]. Можно с
большой уверенностью сказать, что структурное программирование
может быть первым шагом на пути к эффективной методологии про-
граммирования.
Высококачественные программы создаются нелегко. Плохие
программы можно написать многими способами, а хорошие — очень
немногими. Написание хороших программ требует значительно
большего интеллектуального напряжения, чем плохих. Зная это,
программисты должны осознать, что они заняты важной деятель-
ностью, где для получения хороших результатов требуется серьез-
ная работа.
9.4. Проверка программ
Проверка программ состоит из нескольких этапов.
1. Предварительный анализ заключается в тщательном исследо-
вании логики поведения программы до того, как она будет выпол-
няться на машине.
2. Тестирование — это поиск ошибок при помощи запуска про-
граммы с тестовыми начальными данными.
3. Отладка — это поиск причин ошибок, найденных при тести-
ровании, и изменение программы для исправления ^ошибок.
4. Окончательная проверка — последняя контрольная проверка,
совершаемая обычно тем человеком, который написал программу,
перед сдачей ее в эксплуатацию.
5. Официальный прием программы — проверка, осуществляемая
организацией, в которой написана программа, до внедрения про-
граммы в производственную эксплуатацию.
Все пять этапов важны. Основные средства для проверки про-
грамм связаны, однако, с тестированием и доказательством пра-
вильности программ.
Правильность программы может быть доказана при помощи ис-
черпывающей системы тестов, но практически это едва ли осуществи-
мо. Как было указано Дейкстрой, тесты могут показать наличие
ошибок, но не их отсутствие. Для получения хотя бы средней эф-
фективности при проведении тестов необходимо выполнять эту ра-
боту весьма обдуманно. Один из практически применяемых под-
ходов — проверка всех логических путей передачи управления
в программе. При этом предполагается, что если некоторый участок
программы выполняется и в нем есть ошибка, то она сказывается на
конечном результате (или на промежуточных результатах, если они
выдаются). Очевидно, что имеются случаи, когда данное предполо-
жение не верно. Впрочем, как правило, проверка всех логических
путей передачи управления — хорошая отправная точка для вылав-
ливания ошибок. Это не гарантирует правильности программы, но
устраняет много очевидных ошибок. Другой простой и часто эф-
фективный метод заключается в том, что проверяют исключительные
условия, например крайние значения областей переменных. Опыт
показал, что при написании программы часто не учитываются край-
ние условия (например, возможность пустой очереди).
Подход, при котором каждый модуль тестируется по отдель-
ности, также сильно экономит необходимые усилия. Польза такого
подхода поясняется следующим рассуждением. Предположим, что
проверка одного логического пути требует затрат труда, принима-
емых за единицу работы. Рассмотрим процедуру, имеющую п ло-
гических путей. Предположим, что ее вызывают из т мест в другой
процедуре, где имеется, таким образом, т путей с вызовом первой
процедуры. Если эти процедуры испытываются независимо, то по-
требуется п единиц работы для проверки логических путей в первой
процедуре и т единиц для проверки во второй, т. е. всего п + т
единиц работы. С другой стороны, если обе процедуры рассматри-
ваются вместе, в комбинированной программе будет п*гп логиче-
ских путей, что потребует для проверки п»т единиц работы. Оче-
видно, что при независимой проверке нужно значительно меньше
работы.
Независимое тестирование модулей имеет тот недостаток, что
до объединения модулей могут затушевываться трудности интер-
фейса. Так, в приведенной только что схеме вызываемая процедура
может иметь побочный эффект, влияющий на вызывающую проце-
дуру. Такого рода проблемы могут быть решены глобальным тести-
рованием объединенной -программы. Однако это может оказаться
трудным делом — подобрать варианты тестов для полной програм-
мы, которые проверяли бы все логические пути, и в частности те из
них, которые имеют нежелательные побочные эффекты. Если система
построена как последовательность виртуальных машин, тогда мо-
дули каждого уровня могут быть проверены независимо от более
высоких уровней. Эти модули могут быть затем использованы для
проверки следующего уровня без повторного испытания. Если ин-
терфейс строго определен заранее и является единообразным для
всей системы, может оказаться справедливым следующее утвержде-
ние: в интерфейсе модуля не должно появляться никаких трудностей
на уровне более высоком, чем уровень данного модуля.
9.4.1. Правильность программы
Правильность программы, представляющей некоторый алгоритм,
может быть доказана математически. Работы в этом направлении
основываются, в сущности, на двух подходах. Первый подход име-
ет целью построить традиционное математическое доказательство
того, что программа выполняет те функции, для реализации которых
она предназначена. При втором подходе с помощью математической
модели формально устанавливаются свойства программы и правиль-
ность программы выражается формулой исчисления предикатов,
которая затем может быть автоматически проверена программой
доказательства теорем [Кинг, 1969]. Последний метод очень интере-
сен по своим принципам. К сожалению, состояние науки в области
доказательства теорем еще не в полной мере соответствует требова-
ниям, необходимым для доказательства правильности систем.
Первый способ доказательства ведет начало от фон Неймана,
но практическое значение он приобрел только недавно [Флойд,
1971; Хоар, 1971; Лондон, 1970]. Принципиально этот способ весьма
прост. В различных точках программы, скажем в точках р(1),
. . ., р(и), программист должен задать утверждения, выражающие
инвариантные соотношения между переменными в этих точках.
Существует по меньшей мере одно утверждение относительно вход-
ных переменных программы, одно утверждение на каждый логиче-
ский путь и одно утверждение о выходных переменных; причем
последнее определяет то, что должна выполнять программа. Про-
цесс проверки программы проходит следующие этапы.
Предположим, что p(i)— некоторое утверждение1), a p(j) —
следующее утверждение на том же логическом пути данной програм-
мы. Докажем для участка программы между точками p(i) и p(j)
следующее: если утверждение р (/) истинно и операторы на участке
между точками p(i) и р(/) выполняются, то утверждение p(j) истин-
но. Если этот процесс проверки завершен для всех смежных пар
утверждений по всем логическим путям, то по индукции доказана
правильность программы, если при выполнении она когда-либо
останавливается. Данный процесс проверки выявляет лишь частич-
ную правильность (т. е. с точностью до останова программы), и он
должен быть дополнен другим доказательством, касающимся оста-
нова. Заинтересованный читатель может найти примеры этой мето-
дики в литературе [Элспас и др., 1972; Лондон, 1970].
Представляется уместным сделать некоторые полезные замеча-
ния по применению процесса проверки. Во-первых, если не прохо-
дит доказательство правильности программы, то С1ама программа
может быть верной, а использованные утверждения — ошибочными.
Отсюда следует, что творческая часть доказательства состоит в по-
строении утверждений — работе, которая может быть весьма тру-
доемкой для программ внушительных размеров. Доказательства
правильности программ также по большей части очень длинные и
утомительные. Очевидна трудность проверки правильности таких
доказательств. Усилия по доказательству правильности программы
настолько трудоемки, что это часто мешает применению данного
метода в более или менее широком масштабе. И наконец, доказатель-
ство такого типа не защищает от технических ошибок такого рода,
как ошибки при пробивке перфокарт. Кроме того, данный метод не
защищает отдельную программу от ошибок в аппаратуре, которую
при доказательстве обычно полагают исправной. Более важно, од-
нако, что при современном состоянии науки не имеет смысла рас-
сматривать для целей проверки целую систему программного обес-
печения как одну программу.
Метод утверждений является очень общим и гибким методом,
который может использоваться эвристически, не обязательно в свя-
зи с доказательством. Так, в некоторых языках (например, в языке
SUE [Кларк и Хорнинг, 1971]) программист может задавать утверж-
дения, из которых вырабатываются команды контроля ошибок, если
при компиляции задан режим «отладка». Таким способом утвержде-
ния проверяются для некоторых входов. Те же самые утверждения
воспринимаются как комментарии, когда компилятор работает
в обычном режиме. Аналогичный подход был предложен для интер-
активного программирования. В этом случае программист делает
утверждения, относительно которых система пытается доказать либо
их правильность, либо их ошибочность. Обратная связь с системой
г) Обозначения точки и утверждения в точке одинаковы.— Прим, перев.
помогает программисту понять свойства его программы [Сноудон,
1972].
До сих пор доказательство правильности программы рассматри-
валось как деятельность, независимая от проектирования и реали-
зации программ. На самом деле это далеко не так. Во-первых, оче-
видно, что доказывать правильность чужой программы намного
труднее, чем своей собственной. Кроме того, от выбора структуры
и проектирования программ в громадной степени зависит сложность,
а иногда даже сама возможность доказательства правильности про-
грамм. Следовательно, доказательство правильности не должно рас-
сматриваться изолированно; напротив, оно должно быть составной
частью общей работы по проектированию и реализации. Доказатель-
ство правильности может даже подталкивать проектирование про-
грамм в определенных направлениях. Комбинированное применение
методов структурного программирования и методов доказательства
программ во время проектирования и программирования представ-
ляется наилучшим способом получения высоконадежной программы
[Хоар, 1969]. В данном и в следующем разделах доказательство пра-
вильности программ описывается независимо от проектирования,
но читатель должен всегда иметь в виду, что и то и другое — необ-
ходимые части проектирования и реализации. Они разделены только
для того, чтобы более четко описать их свойства.
Разобранный способ доказательства правильности программ
дополняет тестирование и способствует как четкому стилю програм-
мирования, так и аккуратному проектированию программ. Пос-
леднее само по себе является весьма важной целью. В следующем
разделе общий метод будет описан более подробно применительно
к операционным системам.
9.4.2. Правильность систем
Операционные системы бывают слишком велики, чтобы можно
было доказать их правильность; однако точное установление их
свойств, принятых предположений и связанных с ними теорем в зна-
чительной степени способствует достижению надежности систем.
При попытке доказательства правильности программы в качестве
«побочного эффекта» достигается хорошее понимание функциониро-
вания программ. После формального установления всех необхо-
димых свойств, предположений и теорем оказывается, что данная
система достаточно хорошо неформально проанализирована, и
тем самым можно гарантировать ее правильность для всех практиче-
ских целей.
Кроме того, доказательство правильности системы требует очень
строгих описаний предположений о входных данных и других фак-
торах, влияющих на внешнюю среду, в которой работает програм-
ма, Это обстоятельство уменьшает до минимума опасность некоррекр
ного действия системного модуля в результате неправильного обра-
щения к нему. Если тот, кто занимается реализацией, знает, что
правильность программы в конечном счете должна быть доказана,
то это очень благоприятно сказывается на стиле написания и струк-
туре программ. Таким образом, несмотря на то что текущее состоя-
ние науки в вопросе доказательства правильности программ не
может обеспечить полного доказательства правильности больших
систем, уже сами попытки и намерение применить методы доказа-
тельства правильности оказываются полезными на практике.
Свойство правильности простой последовательной программы
выражается как функция, преобразующая входы в выходы, или
как прямое соотношение между переменными в программе. Такое
свойство может быть более или менее прямо доказано исходя из
семантики языка программирования с использованием процесса
проверки, кратко описанного в разд. 9.4.1. Правильность систем
ставит несколько дополнительных проблем [Баллард и Цикритзис,
19731.
Перед тем как пытаться доказать правильность системы, следует
точно установить, что мы понимаем под правильностью системы.
Часто бывает очень трудно дать точное описание функций, выполня-
емых каждым модулем системы. Еще труднее определить, что дела-
ет вся операционная система, взятая целиком. Могут существовать
некоторые очевидные ограничения; например, не должны допускать-
ся тупики. Однако многие свойства, например, такие, как ограни-
чения, связанные с режимом реального времени, формализовать не-
легко. Даже тогда, когда требуемые свойства понятны, их часто
бывает неудобно выражать при помощи функции выходов от входов.
Рассмотрим в качестве примера некоторый процесс, обрабатываю-
щий большую структуру данных, используемую и другими процес-
сами. Пусть данный процесс обладает тем важным свойством, что
после своей работы он оставляет структуру данных в некотором связ-
ном виде, например оставляет список с организацией при помощи
ссылок. Связность можно легко выразить, используя семантику ука-
зателей, но описание ее с помощью функции выходов от входов было
бы весьма громоздким.
В работе большинства систем имеется естественный, или логи-
ческий, параллелизм. Следовательно, необходимы средства для уче-
та возможности параллельной работы. Иногда нужно исследовать
произвольные временные условия, что порождает много различных
случаев, требующих доказательства.
Некоторые из процессов системы в принципе работают всегда.
В самом деле, одно из желательных свойств операционной системы
состоит в том, чтобы она никогда не останавливалась. В операцион-
ной системе не всегда существует строгая связь типа причины и след-
ствия и достаточно простое управление при помощи операторов вызо-
ва и возврата, как это делается для последовательной процедуры,
реализующей какую-либо функцию. Больше того, в системе постоян-
но возникают процессы, которые могут быть описаны при помощи
истории их внутренних состояний. Такие процессы получают поток
входных данных и выдают поток выходных данных. Порядок входов
и выходов может устанавливаться сколь угодно сложным плани-
рующим механизмом каждого процесса.
Некоторые процессы близки к аппаратуре. В работе аппаратуры
нет ничего принципиально сложного, но ее обычно трудно описать.
Одна из причин заключается в том, что сбои аппаратуры могут при-
водить к различным экзотическим ситуациям. На практике эти воз-
можности игнорируются, но при доказательстве правильности они
должны быть учтены. Точное описание свойств аппаратуры необ-
ходимо как часть информации, требуемой для доказательства.
Большая часть описанных выше трудностей в доказательстве
правильности систем может быть преодолена, если принять описан-
ный в разд. 2.2. принцип состояний [Хорнинг и Ренделл, 1973].
В любой момент времени систему можно представить ее состоянием.
Семантику какой-либо программы можно описать тем, как данная
программа влияет на состояние системы, которое характеризуется
значением определенных переменных состояния. Деятельность си-
стемы представляется историей ее состояний. Принцип состояний
позволяет описать каждый процесс на любом уровне абстракции.
Какое-либо свойство может быть, следовательно, описано как связь
между состояниями. Например, при проверке последовательной
программы состояния соответствуют точкам, где определены утверж-
дения. Доказательство правильности ведется по индукции по пос-
ледовательности таких состояний, сменяющих друг друга во время
выполнения программы.
Трудность в использовании принципа состояний связана с тем,
что он требует слишком большой детализации. Для проведения до-
казательства следует обращать особое внимание на специальные
состояния или группы состояний. При доказательстве правильности
последовательной программы хороший выбор утверждений — труд-
ное искусство. В использовании принципа состояний очень нелегко
выбрать подходящие последовательности интересных состояний.
Рассмотрим некоторую систему и историю ее состояний. Свойство
правильности обычно можно определить в виде соотношения состоя-
ний или групп состояний на очень высоком уровне абстракции. На
низком уровне свойства программ (т. е. последовательностей команд,
выполняемых процессами) можно представить в виде соотношений
состояний, тесно связанных с кодировкой команд и последователь-
ностью их выполнения в данном процессе. Доказательство правиль-
ности системы должно перекинуть мост между различными уровнями.
Оно обычно проходит в четыре этапа [Баллард, Цикритзис, 1973].
1. Точно и формально оговариваются свойства, относящиеся
к внешней среде каждого процесса. При этом обычно предполагается
исправность машины, на которой выполняется процесс, и прини-
маются допущения об условиях инициализации данного процесса.
2. Свойства последовательности состояний на низком уровне,
соответствующих активациям процесса, доказываются при по-
мощи программы и семантики языка программирования. Структура
программы и свойства языка программирования оказывают зна-
чительное влияние на трудоемкость данного этапа.
3. Выбираются подходящие состояния и/или группы состояний
более высокого уровня. С помощью свойств, проверенных на этапе 2,
по индукции доказывается правильность всех возможных после-
довательностей данных состояний. Сама индукция не всегда носит
очевидный характер.
4. Свойства правильности формализуются в виде связей между
состояниями на более высоком уровне. Эти связи выводятся из те-
орем этапа 3. Здесь важна структура системы. Если структура си-
стемы удачна, ее свойства могут быть сформулированы в весьма
сжатой форме.
Проблемы проверки свойств программ и систем привлекают
большое внимание [Миллс, 1973]. В настоящее время делается
упор на надежность систем программного обеспечения, и эю при-
дает особую важность внимательному исследованию трудоемкости
программирования. Цель состоит в том, чтобы разработать такую
методику для изготовления и проверки программ, которая обеспе-
чивала бы сверхнадежность систем. Сейчас многие считают, что
подходящей методикой может стать сочетание методов структурного
программирования и методов доказательства правильности про-
грамм. Миллс сделал предположение, что правильная методика су-
ществует, но люди не верят в нее и поэтому не используют соответ-
ствующим образом. Рассмотрим аналогию, приведенную Миллсом.
Пятилетние дети могут играть в совершенную игру «крестики-
нолики», но они не знают, что в этой игре существует оптимальная
стратегия. В результате, если они не очень внимательно играют, то
иногда проигрывают. Семилетние дети знают, что они могут приме-
нить оптимальную стратегию. Поэтому они не проигрывают, если
не хотят. Возможно, в программировании пришло время покончить
с той тактикой, которой пользуются в игре «крестики-нолики» пя-
тилетние дети, и принять стратегию семилетних. Хорошие програм-
мы могут быть написаны теми, кто делает это не спеша и внимательно.
9.5. Оценка эффективности
По мере того как растет сложность вычислительных систем, уве-
личивается и сложность их оценки. В ранних системах большая часть
труда по разработке систем падала на проектирование и реализа-
цию. Эффективность оценивали потом. Однако в связи с увеличением
числа различных видов аппаратуры и элементов программного обес-
печения, многие из которых предназначены для выполнения одних
и тех же функций, внимание изготовителей и пользователей прив-
лечено теперь к поиску разумных методов оценки эффективности
систем уже на этапе проектирования.
При оценке вычислительных систем трудно разграничить харак-
теристики аппаратуры и программного обеспечения. Первые по-
пытки анализа эффективности систем были связаны в основном со
скоростью работы аппаратуры; программное обеспечение играло
только подчиненную роль. В современных мультипрограммных си-
стемах, однако, характеристики «чистой» машины, т. е. машины
без программного обеспечения, не имеют большой практической
ценности. Такие характеристики системы, как пропускная способ-
ность и время прохождения задания, являются в той же мере функ-
цией операционной системы и общей загрузки, как и самой аппара-
туры. Отсюда понятно, что разработчик операционной системы
должен серьезно заниматься проблемой измерения эффективности
системы.
Для того чтобы действенно оценить вычислительную систему,
нужно четко определить цели производимой оценки. Если рассмат-
ривать потенциально произвольное число параметров, ограничен-
ное лишь количеством данных, которые можно собрать, то очень
легко погрязнуть в массе деталей. Необходимо, следовательно, так
ограничить исследование соответствующих свойств, чтобы стоимость
оценки могла остаться в разумных пределах. Такие свойства можно
выделить только при условии, что известны цели оценки.
Говоря более конкретно, можно указать три основные цели из-
мерения эффективности: оценка для выбора, планирование эффек-
тивности, отслеживание эффективности с помощью монитора [Лу-
каш, 1971]. Оценка для выбора нужна в тех случаях, когда сравни-
ваются несколько существующих систем. Обычно хотят иметь такую
комбинацию аппаратуры и программного обеспечения, которая наи-
лучшим образом подходит для нужд данного пользователя. Ис-
ходя из этих нужд, формулируют совокупность критериев выбора;
затем на базе этих критериев сравниваются имеющиеся системы.
Заметим, что для реального выбора необходимо существование по
крайней мере одной реализации каждой системы. Планирование эф-
фективноспги в общем случае делается для систем, которые еще не
реализованы. Используя методы предсказания результатов, раз-
работчики могут проверить свои идеи до воплощения их в аппара-
туре. Отслеживание эффективности с помощью монитора касается
характеристик системы, уже находящейся в эксплуатации. На ос-
новании данных, которые выявляют недостаточную эффективность
в некоторых узлах системы, можно улучшить конфигурацию си-
стемы.
Пусть нам дана цель оценки системы; какие свойства надо иссле-
довать, чтобы выполнить требуемую оценку? Выбор подходящих
характеристик часто так же труден, как и фактическое измерение
этих характеристик. На самом деле трудность получения опреде-
ленных данных с нужной точностью может повлиять даже на выбор
свойств, подлежащих исследованию. Точно так же само принятие
решения в отношении цели оценки в определенной степени зависит
от характеристик, причем от одних в большей степени, чем от дру-
гих. Решающим фактором может быть сумма средств, отпускаемых
на выполнение оценки. В разд. 9.5.2 описаны наиболее часто при-
меняемые критерии эффективности вычислительных систем. В разд.
9.5.3 представлены различные методы, при помощи которых можно
определить действительные значения для этих критериев.
9.5.1. Цели оценки
Упомянутые ранее три цели оценки приблизительно соответст-
вуют проектированию, приобретению и использованию машины.
Помимо подробного описания каждой цели, ниже будет показано,
каким образом эти виды оценок могут коренным образом повлиять
на системы, еще находящиеся на стадии разработки.
На каждой стадии построения системы возможность предска-
зания эффективности может помочь разработчику в проверке новых
идей до их фактического воплощения. Такие предсказания могут
осуществляться с помощью аналитических или имитационных моде-
лей, чаще всего последних. Можно сравнить несколько различных
проектных решений, измеряя при помощи модели, как каждое из
них скажется на всей системе в целом. Кроме того, можно опреде-
лить характеристики всей системы до ввода ее в эксплуатацию. Не-
желательные черты системы можно исправить во время проекти-
рования, когда такие изменения легче всего внести. Знание харак-
теристик выпускаемой системы может дать также лицам, ответст-
венным за сбыт, отправную точку в переговорах о продаже системы
пользователям.
Несмотря на эти очевидные преимущества планирования эф-
фективности систем на этапе их разработки, в прошлом технические
трудности часто снижали эффект таких предсказаний. Поскольку
большая часть имеющихся источников финансирования направля-
ется на проектирование, предсказание эффективности часто на ме-
сяцы отстает от проектирования. Полезные результаты анализа
обычно появляются слишком поздно, чтобы они могли чему-нибудь
помочь. Чтобы предсказание приносило пользу при проектировании
вычислительных систем, оно должно получить достаточно высокий
приоритет и выполняться наравне с остальными работами по про-
екту.
Второй, еще менее используемый аспект планирования эффектив-
ности — это модификация существующих систем. Планирование
может быть также использовано для оценки результатов ожидаемых
изменений в загрузке системы. Лицо, ответственное за эксплуатацию
системы, может использовать эти данные при планировании будущих
изменений в конфигурации системы.
Оценка для выбора включает анализ нескольких существующих
систем с целью выбора такой конфигурации, которая наилучшим
образом удовлетворит потребностям пользователя. Скорость, на-
дежность и стоимость — все это учитывается при выборе. Системы
могут быть разбиты на классы в соответствии с каждым признаком,
который важен для пользователя. По комбинации признаков можно
также рассчитать показатель качества. Эта величина представляет
собой взвешенную сумму признаков, по каждому из которых можно
производить и отдельную классификацию. Система с наивысшим
показателем качества считается самой лучшей из всех сравнивае-
мых систем.
При расширении существующей системы можно сочетать оценку
для выбора и планирование эффективности. При помощи планирова-
ния можно определить эффект от добавления какого-либо средства,
будь то периферийное устройство или пакет системы программного
обеспечения. После этого можно сравнить соответствующие средст-
ва, изготовленные различными производителями, и выбрать из них
наилучшее (т. е. применить оценку для выбора).
Отслеживание эффективности с помощью монитора является од-
новременно и средством для проектирования систем, и методом для
оценки эффективности. Отслеживание изменений в характеристиках
пользователя и системы может помочь «подстраивать» систему таким
образом, чтобы она работала наиболее эффективно. Следовательно,
хорошие средства для отслеживания должны быть обеспечены на
любой установке. Их можно также рассматривать как вспомогатель-
ные средства для выбора и планирования. Данные, описывающие
функционирование системы, используются как для определения ее
места в классификации систем, так и для предсказания изменений,
связанных с изменяющейся загрузкой и конфигурацией. Специаль-
ные методы отслеживания с помощью монитора будут описаны
в разд. 9.5.2.
Помимо того что оценка эффективности помогает в проектирова-
нии, выборе и отслеживании систем, она может оказывать влияние
на разработку будущих систем. Оценка эффективности раскрывает
характеристики загрузки систем и требований пользователя, и
тем самым она помогает разработчикам «кроить» новые системы,
удовлетворяющие уже известным требованиям. Проекты, не обес-
печивающие надежности и неэффективные, можно своевременно об-
наружить и переработать. Наиболее важное перспективное исполь-
зование оценки эффективности могло бы состоять, по-видимому, в за-
креплении стандартов для эффективности систем. Какое-либо бюро
по выдаче свидетельств на программы, нечто вроде организации по
страхованию, могло бы помочь в достижении минимального уровня
эффективности в программном обеспечении вычислительных машин.
Однако, прежде чем будут установлены такие стандарты, требуется
еще много исследований, которые ответили бы на вопрос, что такое
«хорошая» эффективность.
9.5.2. Критерии эффективности
Имеются три основных критерия эффективности: пропускная
способность, время прохождения (или ответа) и доступность [Ка-
лингэрт, 1967]. Пропускная способность измеряет рабочую мощность,
т. е. количество работы, которая может быть выполнена за единицу
времени (в среднем). Время прохождения — это среднее время, за
которое одно задание проходит через пакетную систему; время от-
вета — это время, затрачиваемое интерактивной системой на выпол-
нение команды пользователя. Доступность — это мера продол-
жительности полезной работы системы за день. Сюда входит и время
для вспомогательных работ по поддержанию системы, и время не-
ожиданных простоев. Иногда для определения доступности можно
использовать среднее время между сбоями. Описанные выше крите-
рии ориентированы на пользователя, поскольку они измеряют то,
что система способна сделать для своих пользователей. Эти крите-
рии и не должны касаться того, как система предоставляет свои
услуги.
Другой класс критериев, называемых критериями производи-
тельности, раскрывает функционирование системы изнутри. Такие
внутренние характеристики, как накладные расходы, использова-
ние ресурсов и скорость машины, не являются существенно важны-
ми для пользователей (за исключением, возможно, того, что эти
критерии связаны со стоимостью). В самом деле, оптимизация не-
которых из этих критериев может оказаться вредной для пользова-
теля. Так, например, улучшение использования ресурсов может
увеличить для некоторых пользователей время прохождения. Тем
не менее указанные критерии производительности оказывают су-
щественную помощь разработчику и руководителю, когда надо оп-
ределить причину неэффективной работы системы.
Хотя типы критериев эффективности, полезных для ее оценки,
хорошо известны, все же бывает не всегда достаточно ясно, как про-
изводить соответствующие измерения. Это особенно верно для кри-
териев производительности, так как внутренние характеристики
системы скрыты от глаз. В следующем разделе говорится о раз-
личных способах, которыми можно определить эти характерис-
тики.
9.5.3. Методы количественной оценки эффективности
Способы оценки эффективности варьируются очень широко в за-
висимости от измеряемого признака и от ресурсов, выделяемых для
анализа. Методы оценки могут быть разбиты на три категории: ана-
литические, эмпирические и имитационные. При аналитическом под-
ходе рассматривается абстракция системы в виде математической
модели. Затем модель анализируется и полученные результаты при-
меняются к исходной системе. Эмпирические методы предусматри-
вают сбор данных на реальной системе. Эти данные затем могут либо
непосредственно использоваться (например, скорости выполнения
команд), либо вводиться в качестве исходной информации для пос-
ледующего анализа (например, в моделях с трассировкой). В ими-
тационных методах модель представляет собой абстракцию реальной
системы, в которой удалено много несущественных деталей. Пред-
полагается, что сбор данных на модели проще, чем сбор аналогич-
ных данных на исходной системе. Полученные на модели дан-
ные затем используются для описания свойств моделируемой сис-
темы.
Ни один из перечисленных выше методов не является идеальным
для всех задач оценки. Для каждого метода, однако, существуют
ситуации, где он превосходит все остальные. В последующих разде-
лах описаны наиболее сильные и слабые стороны, а также наиболее
важные приложения каждого метода.
9.5.3.1. Аналитические методы
Имеется несколько типов математических моделей, применимых
к оценке вычислительных систем. Наиболее широко распространено
использование теории очередей. Этот подход применим к решению
проблем планирования обслуживания как для центральных про-
цессоров, так и для периферийных устройств. В этих моделях при-
нимается определенная гипотеза относительно вида функции, опи-
сывающей распределение моментов появления задач. Для процес-
сора выбирается стратегия планирования обслуживания задач.
Затем из заданных характеристик самого процессора, таких, как
время, требуемое для одной задачи, выводят характеристики си-
стемы. Рассмотрим, например, очередь процессов, которые должны
выполняться на центральном процессоре. Может оказаться полез-
ным знание предполагаемого времени ожидания для каждой задачи
(т. е. времени ее прохождения) и среднего числа заданий, обслужи-
ваемых за единицу времени (т. е. пропускной способности). Модели
теории очередей особенно успешно используются при анализе пла-
нирования работы центрального процессора, барабанов и дисков.
Коффман [1969], Фуллер и Баскет [1972] проанализировали работу
барабанов в отношении возможных длин очередей и времени ожида-
ния при различных стратегиях планирования обслуживания за-
просов и организации барабанов. Стратегия планирования для ди-
сков была исследована на среднее время ожидания [Тернбул, 1972]
и на предполагаемое время поиска [Тиори и Пинкертон, 1972].
Для начального ознакомления с методами теории очередей реко-
мендуем читателю книги Морзе [1958] и Коффмана и Деннинга
[1973].
В оценке систем применяются также методы комбинаторного ана-
лиза и математического программирования. Комбинаторные приемы
используются для доказательства оптимальности одной из несколь-
ких стратегий планирования [Севсик, 1971]. В анализе систем при-
меняются также методы линейного и динамического программиро-
вания. Эти методы, как правило, более пригодны на этапе проекти-
рования, чем на этапе оценки. Все указанные методы, однако, имеют
серьезные недостатки.
Главная трудность, связанная с использованием аналитических
методов, состоит в том, что они не дают возможности промоделиро-
вать сложные взаимодействия нескольких подсистем. Для единич-
ной подсистемы, например для периферийного устройства, анализ
возможен при определенных упрощающих предположениях; но
эти предположения часто оказываются неприемлемыми, когда си-
стема рассматривается с более общей точки зрения. Увеличение
количества переменных и распределений вероятностей обычно при-
водят к такому усложнению абстракции, что аналитические решения
становятся невозможными.
Кроме того, некоторые части системы трудно описать в матема-
тических терминах. Большие части программного обеспечения не-
разумно анализировать теоретическими методами. Даже те компо-
ненты системы, которые можно промоделировать, часто приводят
к конструкциям, слишком чувствительным к изменениям парамет-
ров. Это значит, что какое-либо небольшое изменение структуры
данных компонент может сделать полученный аппарат совершенно
непригодным. Отметим также, что обоснованность многих упроща-
ющих предположений часто носит сомнительный характер. Так,
например, при мультипрограммировании возникают явления, зави-
сящие от стратегии планирования процессора. Хотя эти явления
рассматриваются обычно как случайные величины, эмпирические
данные не достаточно строго подтверждают эту гипотезу. Однако
большинство таких ограничений относится к более общим ситуа-
циям. Аналитические методы могут давать приемлемые результаты
при оценке эффективности малых подсистем, и эти результаты
можно использовать для реальных машин. Кроме того, аналити-
ческие методы очень полезны в решении вопросов о том, что надо
измерять и как оценивать эмпирические данные.
9.5.3.2. Эмпирические методы
Наиболее распространенные, по-видимому, методы оценки эф-
фективности основаны на сборе данных с системы во время ее работы.
Эти эмпирические методы делятся на два класса. Одна группа мето-
дов использует такие характеристики системы, как время цикла про-
цессора и время выполнения команд, прилагая их к модельным
примерам. К этим методам относится, в частности, анализ отдельных
команд, смесей команд и стержневых программ. Вторая группа ме-
тодов связана со сбором данных на реально выполняемых програм-
мах. Для получения сопоставимых данных на разных машинах мож-
но пропускать искусственные или реальные программы.
Один из ранних методов оценки системы использует время цик-
ла команды и время выполнения команды сложения в качестве ба-
зовых значений. Хотя эти величины и дают приблизительное поня-
тие об общей скорости машины, очевидно, что они не годятся для
точных измерений. Когда рассматривают только время цикла и
время сложения, игнорируют слишком много характеристик маши-
ны. Ни одна из команд не дает полного представления о скорости
машины. Кроме того, при использовании этого метода трудно ана-
лизировать ввод-вывод, который во многих системах является оп-
ределяющим фактором.
Недостатки, связанные с использованием времени цикла и вре-
мени сложения, можно в какой-то степени преодолеть, если взять
взвешенное среднее значение скоростей выполнения команд. Это
среднее значение, называемое средним смеси команд, учитывает
скорости выполнения команд пропорционально частоте их появле-
ния в средней программе. Для различных приложений могут быть
получены различные смеси. Смеси для научных приложений имеют
большие веса для арифметических команд, а смеси для коммерческих
приложений имеют большие веса для команд, связанных с обработ-
кой, преобразованием и пересылкой данных. Подсчитанная соот-
ветствующим образом средняя скорость выполнения команды ис-
пользуется как мера мощности машины.
Стержневая программа (замечание: этот термин не имеет отно-
шения к программе-стержню системы SUE) вычисляет некоторую
стандартную функцию, которая, как предполагается, характери-
зует среднюю загрузку машины. Время выполнения этой программы
получается на основании известных скоростей команд, соответст-
вующих каждому оператору на машинном языке; результат сум-
мирования по всем командам с весами, определяемыми по частоте
выполнения каждой команды, оценивает время выполнения стерж-
невой программы. Главное преимущество критерия времени выпол-
нения стержневой программы над критерием среднего времени смеси
состоит в том, что с помощью стержневой программы можно учесть
специфические черты системы, связанные с программированием.
Для максимального уменьшения времени выполнения стержневой
программы можно пользоваться командами с мультиадресами и ко-
мандами над стеком. Многие свойства, которые при употреблении
смеси команд учитываются с низкой частотой использования, могут
оказаться важными, если их включить в стержневую программу.
Многие приложения этой методики используют взвешенное среднее
нескольких стержневых программ; при этом охватывается широкий
спектр вычислительных задач.
Кроме измерения скорости аппаратуры, стержневые программы
могут частично использоваться в исследовании критических узких
мест в аппаратуре и в оценке программного обеспечения. Разработ-
чик анализирует, на какие команды расходуется большая часть
времени работы, и может определить, где увеличение скорости вы-
полнения команд будет наиболее эффективно. Кроме того, исследо-
вание кода, генерируемого’различными компиляторами по стерж-
невой программе, может обеспечить грубую оценку эффективности
компиляторов.
Эталонная1) программа — это закодированный алгоритм, кото-
рый вычисляет обычную полезную функцию, типичную для загрузки
системы. Эталонные программы отличаются от стержневых тем, что
они являются реальными программами. По эталонным программам
считаются подлинные коммерческие и научные задачи. Стержневые
программы, напротив, могут быть только частями функций, отно-
сительно которых предполагается, что они характерны для типовых
вычислений.
Чтобы получить достаточно хорошее представление о распреде-
лении приложений, обычно пропускают большое число эталонных
задач. Метод с использованием эталонных задач — первый из опи-
санных здесь, который включает рассмотрение ввода-вывода и сис-
темного программного обеспечения. Эталонные задачи реально вы-
полняются, поэтому результаты задержек, связанных с вводом-вы-
водом, и влияние накладных расходов операционной системы сказы-
ваются на соответствующих временных показателях.
Оценка системного программного обеспечения приводит к новым
проблемам. Трудно сравнивать быстрые и оптимизирующие компи-
ляторы. Точно так же медленная операционная система иногда
обеспечивает больше возможностей, чем более быстрая; таким
образом, временные показатели — не всегда правильная основа для
сравнения. Кроме того, в противоположность аппаратуре, програм-
мное обеспечение обычно меняется за время срока службы машины.
Сопровождение системного обеспечения изготовителем подразуме-
вает улучшение старых программ и предоставление новых функций.
Иногда даже ненадежная программная система за несколько меся-
цев может быть приведена в порядок и стать образцовой. Репутация
х) В оригинале «benchmark».— Прим. ред.
компании-изготовителя в отношении того, как быстро она улучшает
свое программное обеспечение, может повлиять на оценку системы.
Следовательно, легкость внесения изменений в программное обеспе-
чение представляет собой параметр, который весьма трудно оценить.
Синтетическая программа — это (обычно машинно-независимая)
процедура, которая проверяет множество свойств системы (напри-
мер, ввод-вывод, скорость выполнения команд, операционную си-
стему) единообразным способом. Отличие синтетических программ от
стержневых состоит в том, что синтетические программы представ-
лены в коде, полностью готовом для выполнения. Синтетические
программы отличаются от эталонных тем, что они не решают реаль-
ных прикладных задач и могут быть сделаны специально для оценки.
Синтетические программы составляются так, чтобы их поведение
в максимальной степени соответствовало реальным программам.
Они производят вычисления, делают ввод-вывод и могут обращаться
к некоторым системным функциям. Их преимущества перед эталон-
ными программами в том, что синтетические программы могут быть
сделаны простыми, легко понятными и компактными.
Наиболее часто используемые средства для оценки — это, несом-
ненно, аппаратные и программные мониторы. Монитор представ-
ляет собой программу или запаянный в аппаратуру «черный ящик»;
он собирает данные об эффективности во время нормальной эксплу-
атации системы. Мониторы могут собирать весьма разнообразные
данные, включая отслеживание адресов, подсчет ссылок, загрузку
каналов и памяти, статистику по заданиям. Отслеживание с по-
мощью монитора — это такой эмпирический метод, который позво-
ляет сделать внутреннюю работу системы видимой.
Обычно аппаратные мониторы конструируются как придаток
к первоначальной системе, но в современных вычислительных си-
стемах некоторые средства отслеживания включаются непосредст-
венно в систему. В принципе такими средствами можно измерять
любое движение информации. Однако аппаратные мониторы совер-
шенно безразличны к существу собираемых ими данных (поэтому,
например, полная информация об отслеженных адресах может за-
писываться на магнитную ленту порядка нескольких минут). Отсюда
следует, что аппаратные мониторы должны применяться избира-
тельно, так, чтобы собирать только некоторую информацию о собы-
тиях в соответствии с заданным образцом. Методы отслеживания
с помощью аппаратных мониторов позволяют наиболее легко реа-
лизовать счетчики загрузки устройств и доступа к устройствам.
Свойства программ пользователя и системных процедур лучше
всего отслеживаются мониторами программного обеспечения. С по-
мощью небольшого программного пакета можно легко получать та-
кие компоненты статистики заданий, как использование ресурсов
и частота вызова системных процедур. Следует учесть, однако, что
дополнительное отслеживание программными мониторами требует
расхода времени центрального процессора и памяти и, следователь-
но, уменьшает эффективность системы. Аппаратные мониторы хотя
и стоят, как правило, дороже, не влияют на эффективность основной
системы. Какая-то часть отслеживания с помощью монитора произ-
водится в течение всей жизни системы (например, учет времени вы-
полнения задания); в связи с этим необходимо идти на компромисс,
учитывая стоимость аппаратных мониторов и ухудшение эффектив-
ности вследствие применения программных мониторов.
Было показано, что тщательно разработанные методы отслежи-
вания программными мониторами могут ограничить уменьшение
эффективности системы всего одним процентом общего времени про-
цессора. К сожалению, во многих системах нелегко проводить от-
слеживание, так как они проектировались без учета этих возмож-
ностей. Полезным средством для отслеживания с помощью монитора
была бы, например, возможность включать небольшие процедуры
в любой путь связи между модулями.
9.5.4. Имитационные методы
Имитация обеспечивает выполнимый без больших затрат способ
тестирования системы и оценки последствий, связанных с измене-
ниями проекта. Основные элементы системы моделируются в неко-
торой программе для вычислительной машины; выполнение этой
программы имитирует работу самой системы. По существу, имеется
два типа моделирования: трассировочное управление и управление
с помощью модели. Трассировочное управление использует данные,
собранные на изучаемой системе монитором. Эти данные представ-
ляют шаблон поведения системы, который подается на вход модели.
При имитации, основанной на управлении с помощью модели, ком-
поненты поведения системы рассматриваются как случайные функ-
ции. Например, при имитации канала барабана, время доступа мо-
жет быть промоделировано по закону равномерного распределения
вероятностей (управление с помощью модели) или по реальной
кривой (трассе) наблюдавшихся времен доступа (трассировочное
управление). Выбор метода зависит от того, имеются ли отснятые
данные и насколько точно можно промоделировать поведение си-
стемы случайной функцией.
Метод имитации основан на предположении, что модель системы
легче программировать и отслеживать, чем саму исходную систему.
Несмотря на то что это соотношение в среднем выполняется, ни один
из методов не является особенно дешевым. Стоимость моделирования
зависит от того, насколько детально система отражена в модели.
Большее число деталей означает более точную модель, которая,
возможно, будет медленнее работать. Упрощая модель, можно до-
стигнуть увеличения скорости выполнения за счет точности. Часто
бывает трудно определить границу, за которой дополнительные де-
тали больше не оправдывают увеличения стоимости. Выбор степени
подробности модели — это нечто большее, чем просто вопрос эко-
номической целесообразности, так как результаты моделирования
считаются достоверными только после статистической проверки
модели.
Высокая стоимость моделирования препятствует получению
большинства оценок существующих систем. Однако моделирование
полезно при планировании эффективности системы на стадии про-
ектирования. Для определения эффективности предложений по
проекту они могут быть испытаны на модели. Проблема состоит
в том, чтобы дать людям, занимающимся моделированием, достаточ-
но ресурсов для ведения работы на одном уровне с остальными участ-
никами проекта. Многие попытки моделирования потерпели неу-
дачу из-за того, что между проектированием компоненты и включе-
нием ее в модель было большое запаздывание. Правильно использу-
емое моделирование является мощным средством оценки. И тем не
менее нет оснований считать, что оно станет достаточно недорогим
и точным, чтобы в ближайшем будущем заменить аналитические или
эмпирические методы.
За исключением немногих аналитических методов, имеющих
практическую ценность, методы оценки эффективности в настоящее
время относятся более к области искусства, чем науки. Большая
часть методов работает лишь для определенного случая. Те методы,
которые можно считать проверенными, обычно слишком дороги.
Моделирование, несомненно, эффективно, но его стоимость делает
его недоступным для большинства операций, выполняемых на
машине.
9.6. Заключение
В 8-й и 9-й главах обсуждались проектирование и реализация
высококачественных систем программного обеспечения. В реальной
практике, если применить один или все описанные методы, полу-
ченная система не будет все-таки совершенной системой програм-
много обеспечения. Чтобы гарантировать практическую надежность
и эффективность системы, необходимо признать как факт наличие
недостатков и неизбежность появления ошибок. Каждый модуль
системы и сами пользователи должны работать, защищая себя оп-
ределенным образом. Здесь важно иметь соответствующие рабочие
процедуры. Например, целостность информации следовало бы обес-
печить частыми выдачами изменений и/или полными выдачами. Клю-
чевая информация системы (например, справочники) должна быть
не только защищена, но и продублирована. И наконец, свести к ми-
нимуму потери от сбоев могут хорошие средства повторного запуска.
Программное обеспечение никогда не бывает полностью заморо-
женным. Оно имеет жизненный цикл, включающий модификации.
Следовательно, с практической стороны важно поддержание изго-
товленного программного обеспечения. Новые версии системы вво-
дятся при функциональных изменениях и исправлении найденных
ошибок. Биледи и Леман [1971] проделали с помощью модели очень
интересное исследование об увеличении сложности поддержания
систем. Показано, что при определенных условиях усилия по под-
держанию системы могут расти со временем по экспоненциальному
закону. Эти результаты были также подтверждены измерениями
трудовых затрат по поддержанию одной существующей системы.
Отсюда можно прийти к выводу, что некоторые системы програм-
много обеспечения в конце концов могут оказаться кандидатами
в отставку. Оказывается, что легче переписать их, чем поддерживать.
Здесь имеется интересная философская интерпретация. Програм-
мное обеспечение проектируется и реализуется, затем оно живет
(и подает надежды) и в конце концов умирает.
Задания
9.1. Опишите относительные достоинства языка PL/I как языка ре-
ализации систем. Какие желательные свойства в нем отсутствуют?
Без каких его свойств можно было бы обойтись? Обоснуйте ваш ответ.
9.2. Укажите преимущества и недостатки использования быстрого
диагностического компилятора для студентов, например WATFIV
или PL/С, в качестве средства обучения хорошим программистским
навыкам.
9.3. Разберите несколько программ или написанных вашими кол-
легами, или опубликованных в литературе и подготовьте отзыв
на каждую из них. Разберите одну из ваших старых программ и на-
пишите отзыв. Можете ли вы указать в литературе такую программу,
которую бы вы считали образцом программирования?
9.4. Подготовьте список этапов, необходимых для переноса си-
стемы на новую машину (т. е. генерации системы). Подготовьте спи-
сок этапов, необходимых для запуска данной системы (т. е. началь-
ной загрузки процессора).
9.5. Один из применяемых на практике приемов программирова-
ния заключается в том, что программу пишут быстро и затем, ис-
пользуя хорошие средства отладки и тщательное тестирование, на-
ходят ошибки. Укажите достоинства этого метода в сравнении с до-
стоинствами структурного программирования. Опишите эксперимент
для сравнения двух методов программирования.
9.6. Докажите правильность программы, описывающей отношение
поставщик — потребитель на рис. 2.7. Вы должны строго опреде-
лить операции над семафорами и свойства их реализации. Какую
гарантию вы могли бы дать, что данная программа будет выпол-
няться безошибочно?
9.7. Укажите, какое влияние на доказательство правильности ока-
зывает структура программы. Есть ли связь между структурой про-
граммы и структурой доказательства? Подтвердите ваши ответы
тщательным разбором на конкретном примере программы и дока-
зательства ее правильности, например программы из работы Лон-
дона [1970] или Хоара [1971].
9.8. Опишите кратко порядок выдачи «палатой программного обес-
печения» сертификатов о качестве программ. Другими словами,
подготовьте последовательность шагов, которые подтверждали бы
наличие таких желательных качеств программы, как надежность,
эффективность, документированность и т. д.
9.9. Какой недостаток аппаратуры самый серьезный для системы?
Каким образом в такой ситуации можно преодолеть потерю целост-
ности системы?
9.10. Найдите в языке PL/I примеры конструкций, которые, по
вашему мнению, приводят к частым ошибкам. Хотели бы вы изба-
виться от этих конструкций? Хотели бы вы заменить их на другие
конструкции?
9.11. Для увеличения надежности иногда используется избы-
точность аппаратуры. Применим ли принцип избыточности в от-
ношении надежности программного обеспечения? Приведите пример.
9.12. Найдите в литературе три программы, которые были бы или
неправильными, или неудачно построенными, или неэффективными.
Для исправления положения предложите другие программы.
9.13. Определите набор операторов управления, использование
которых устранило бы необходимость в операторе GO ТО. Докажите,
что предложенный набор достаточен. Можете ли вы доказать, что
каждый из операторов набора необходим?
9.14. Почему так много людей выступают против оператора GOTO,
в то время как исключить из аппаратуры команду перехода JUMP
предлагают лишь «немногие?
9.15. Представьте, что вам нужно приобрести новый пакет програм-
много обеспечения. Приведите список критериев фактической эф-
фективности, которым, как вы ожидаете, должен был бы удовлет-
ворять данный пакет. Сравните ваш список со стандартным контрак-
том по программному обеспечению.
9.16. Предположим, что вы имеете установку, где центральная часть
изготовлена фирмой X, периферийные устройства — фирмой Y,
операционная система разработана фирмой X, система базы дан-
ных — фирмой Z и прикладные программы — вами. Опишите про-
цедуру локализации ошибки и наметьте подходящую бригаду по
поддержанию системы.
9.17. Подготовьте сравнительное описание различных языков
для реализации систем.
9.18. Подготовьте список средств для оценки эффективности. При-
ведите примеры их использования.
9.19. Проведите тщательное изучение выбора оборудования. Опи-
шите, например, преимущества оборудования машин IBM перед
установкой CDC в вашем университете.
Глава 10
ПРИМЕРЫ СИСТЕМ
10.1. Введение
Изучение операционных систем не носит чисто теоретического
характера, когда идеи изучаются сами по себе. Человек расширяет
свои познания в области операционных систем для того, чтобы на-
учиться их проектировать, создавать и использовать. Помимо изу-
чения отдельных аспектов операционных систем, важно понять, как
согласуются друг с другом все элементы в системе в целом. Прими-
тивы для организации взаимодействия процессов, механизмы защи-
ты, организация управления памятью и системы ввода-вывода не
проектируются изолированно. Эти элементы взаимодействуют, и они
должны проектироваться и использоваться с учетом этого обстоя-
тельства. В этой главе описываются две операционные системы,
чтобы помочь читателю наглядно представить себе, как взаимодейст-
вуют в системе основные компоненты, описанные ранее в данной
книге.
Рассматриваемыми системами являются операционная система
«Венера», разработанная в корпорации MITRE [Лисков, 1972; Ху-
берман, 1970], и ядро операционной системы SUE, которая разра-
ботана в университете Торонто [Севсик и др., 1972]. Эти две системы
были выбраны как из-за того, что они резко различаются по харак-
теристикам, так и потому, что они имеют четкую структуру. Системы
сильно отличаются по размерам, структуре аппаратуры, методам
синхронизации, защите и целевому назначению. Обе системы, одна-
ко, были спроектированы с помощью структурного подхода. В об-
щей структуре систем четко выделяются уровни абстракции и вир-
туальные машины, что чрезвычайно облегчает точное и ясное опи-
сание систем.
Ядро системы SUE спроектировано для работы на семействе
машин IBM/360. Одна из основных целей проекта SUE заключалась
в применении современной методики построения структурно-орга-
низованных систем для обычной машины. К моменту написания
этой книги система SUE была полностью спроектирована и частично
реализована.
Система «Венера» — это полная интерактивная система для малой
микропрограммной машины Interdata 3. Эта машина совсем не по-
хожа на большие, быстрые и дорогие машины серии IBM/360. Боль-
ше того, она является их полной противоположностью. В отличие
9 № 1250
от проекта SUE группа, разрабатывавшая систему «Венера», могла
с помощью микропрограмм устанавливать нужные ей характери-
стики аппаратуры. Возможность выбора требуемой аппаратной
структуры очень благотворно сказалась на проектировании опе-
рационной системы. Это обстоятельство и определяет коренное от-
личие системы «Венера» от системы SUE, в которой особенности ком-
понент оборудования машин IBM/360 сильно затрудняют создание
операционной системы со стройной структурой.
И система «Венера», и система SUE в качестве основной вычис-
лительной единицы используют процессы. После предпринятой
вначале попытки воспользоваться «почтовыми ящиками» группа,
работавшая над проектом SUE, остановилась в конце концов на
механизме связи с хорошо выраженной структурой, называемом
«средства» [Севсик и др., 1972]. Синхронизация в системе «Венера»
выполнена с помощью семафоров. Эти две системы являются хоро-
шими примерами использования для синхронизации примитивов
высокого и низкого уровней.
Таблица 10.1
Сравнение систем SUE и «Венера»
Характеристики SUE «Венера»
Оборудование Быстродействующее, боль- шое, дорогое Фиксированный набор команд Маломощное, небольшое, не- дорогое
Структура обору- дования Микропрограммируемое
Структура памяти Статическое распределение с помощью базовых реги- Сегментная и страничная организация
Целевое назначе- стров Ядро мультипрограммной Полная интерактивная си-
ние системы стема
Синхронизация процессов Средства Семафоры
Аппаратура ввода- Аппаратные каналы, устрой- Микропрограммные каналы,
вывода ства управления и устрой- ства ввода-вывода аппаратные каналы для ленты и диска
Защита Защита, основанная на ме- ханизме возможностей Нет механизмов защиты
Учет Через аппарат возможно- стей Микропрограммное управле- ние базисным процессом сбора статистики
Предоставляемые Дисковая система управле- Ленточная система управ-
системой функ- ния файлами ления файлами
циональные воз- Телетайпная система ввода- Телетайпная система ввода-
можности вывода Менеджер ресурсов Возможность подсоединения новых подсистем вывода Совместное использование сегментов при помощи об- щих справочников Ассемблер, редактор и от- ладчик
Системы «Венера» и SUE отличаются и в нескольких других
аспектах. Пользователи системы «Венера» по существу совместно
используют всю машину и память, что затрудняет организацию
защиты. В системе SUE, напротив, процессы надежно защищены
с помощью механизма возможностей. Система SUE предоставляет
дисковую систему управления файлами, основанную на использова-
нии механизма возможностей: система «Венера» предоставляет лен-
точную систему управления файлами без обеспечения защиты. На
самом деле, кроме примененного в них основного принципа проек-
тирования структурно-организованных систем, SUE и «Венера»
имеют очень мало общего. Основные характеристики обеих систем
отражены в табл. 10.1.
Оставшаяся часть этой главы посвящена непосредственно описа-
нию систем. Система SUE описана в разд. 10.2, а система «Венера»—
в разд. 10.3. В последнем разделе для заинтересованного читателя
кратко упоминаются несколько других систем.
10.2. Система SUE
10.2.1. Введение
SUE — это название ядра операционной системы, разработанной
в университете Торонто для семейства машин IBM/360. Система
SUE не является полной системой в том смысле, как система OS/360.
Больше того, это только ядро операционной системы (см. разд. 1.2).
Простая дисковая система управления файлами, аппарат распре-
деления ресурсов, защиты и учета, система ввода-вывода, основан-
ная на пишущей машинке, и аппарат для порождения и уничтожения
асинхронных процессов составляют основу для построения несколь-
ких защищенных, независимых подсистем, работающих под управ-
лением системы SUE (например, редактора текстов, пакетной систе-
мы и интерактивной системы). Описание ядра системы SUE разде-
лено на две части. В разд. 10.2.2 кратко говорится о структуре связи
между процессами и распределении ресурсов в системе SUE. В пос-
ледующих разделах описаны фактические средства, предоставля-
емые системой SUE пользователям.
10.2.2. Структура системы SUE
10.2.2.1. Процессы и связь
Ядро системы SUE состоит из группы асинхронных процессов,
каждый из которых выполняется на своем виртуальном процессоре.
Каждый процесс, кроме первого, создается другим процессом. Сле-
довательно, каждый процесс создается некоторым одним процес-
сом, который будем называть отцом, и сам может создать несколько
2*
процессов, называемых сыновьями. Старшинство процессов опреде-
ляется ориентированным графом, называемым генеалогическим де-
ревом (рис. 10.1). Дуга направлена из вершины А в вершину В тог-
да и только тогда, когда процесс А является отцом процесса В. Ге-
неалогическое дерево служит для системы базисной структурой.
Оно, в частности, определяет все возможные пути связи между
процессами.
Рис. 10.1. Генеалогическое дерево в системе SUE. (Дуга направлена из вершины
А в вершину В, если процесс А валяется отцом процесса В.)
Механизм связи между процессами в системе SUE представляет
собой модифицированную форму мониторов Хоара, называемых
«средствами». Средство представляет собой процесс, который при-
нимает запросы на обслуживание от потомков при помощи опера-
ций вызова. Средства реализуются с помощью трех примитивов
(элементарных операций): Вызвать средство. Принять вызов средст-
ва и Закончить обработку вызова средства. Операция «Вызвать
средство» представляет собой запрос от вызывающего процесса на
обслуживание со стороны одного из предков (т. е. отца, деда, пра-
деда и т. д. по генеалогическому дереву). Вызывающий процесс
указывает тип запроса на обслуживание, передавая средству неко-
торое количество параметров. Когда процесс возбуждает такую
операцию, его выполнение временно приостанавливается. Выпол-
нение процесса возобновляется только после того, как его запрос
на обслуживание будет выполнен.
Каждое средство обслуживает запросы одного или нескольких
различных типов; причем тип определяется одним из параметров
вызова. Запросы на обслуживание принимаются с помощью опе-
рации принятия вызова средства, которая обеспечивает извещение
средства, выдавшего операцию, об очередном невыполненном запросе
определенного типа (т. е. о самом раннем непринятом вызове средст-
ва данного типа). Если таких запросов нет, средство блокируется
до появления такого запроса. Путем изменения некоторого пара-
метра средство может сделать операцию принятия «условной», и
тогда оно не будет блокироваться, если нет невыполненных запросов.
После принятия вызова средства данное средство осуществляет
некоторые действия по обслуживанию запроса. Затем средство дает
вызывающему процессу разрешение продолжать работу путем вы-
полнения примитива «Закончить обработку вызова средства».
В системе SUE аппарат средств используется для реализации
уровней виртуальных машин. Каждый процесс на генеалогическом
дереве может предоставить средства всем своим потомкам. Если,
например, процесс В на рис. 10.1 обеспечивает «средство системы
управления файлами», то все потомки процесса В (т. е. процессы
С, D, Е, F, G и Н) могут пользоваться системой управления фай-
лами, возбуждая вызов средства, который будет выполнен процес-
сом В. Можно считать, что процессы С, D,..., Н выполняются на
некоторой виртуальной машине, в которую включена система уп-
равления файлами. Когда процесс возбуждает вызов средства, он
не знает, какое средство обслуживает данный вызов. Ему известно
только, что его виртуальная машина предоставляет это средство.
Таким образом, каждый процесс использует виртуальную машину,
которая полностью определяется средствами, имеющимися у его
предков. На рис. 10.2 показано фактическое генеалогическое дерево
для ядра системы SUE. Функции специальных средств будут опре-
делены в последующих разделах.
Средства, о которых говорилось выше, называются процессами
центрального процессора (ЦП). Кроме процессов ЦП, в системе SUE
имеются два типа псевдопроцессов, называемых процессами кален-
дарного времени и буферными процессами. Ни буферные процессы,
ни процессы календарного времени не потребляют процессорного
времени. Каждый процесс ЦП имеет право порождать процессы
любого из трех типов; при этом он должен отказаться от некоторых
из своих ресурсов, таких, как память и быстродействие процессора,
в пользу каждого из процессов-сыновей. После создания процесс
в зависимости от своего типа выполняет следующие функции.
1. Процесс календарного времени. Этот процесс представляет со-
бой по существу будильник, который по истечении определенного
интервала времени производит вызов отца. После создания процесс
календарного времени ожидает получения от своего отца первого
временного интервала.
2. Буферный процесс. Процесс ЦП может буферизовать свои вызо-
вы средств с помощью порождения буферного сыновнего процесса.
Рис. 10.2. Структура генеалогического дерева в системе SUE. (Пунктирная линия
отмечает границу ядра системы SUE.)
Буферный процесс производит вызов средства по поручению отца,
делая вызов средства некоторого определенного предка. Буферный
процесс (а не отец) должен ждать выполнения этого запроса на об-
служивание. Когда вызов средства выполнен, буферный процесс
снова вызывает отца и сообщает ему, что буферизованный вызов
средства выполнен.
Буферные процессы очень похожи на гнезда почтовых ящиков.
Когда процесс ЦП хочет использовать некоторое средство, он по-
рождает буферный сыновний процесс (т. е. посылает сообщение),
который производит данный вызов. После выполнения вызова ука-
занного средства, буферный процесс снова вызывает своего отца
(т. е. отвечает на посланное сообщение). В то время, когда буфер-
ный процесс ожидает обслуживания со стороны вызванного им
предка, отец данного процесса (который должен получить ответ)
может продолжать выполнять другую работу.
3. Процессы ЦП. Эти последовательные процессы могут быть
весьма разнообразными. Некоторый процесс ЦП может объявить
себя процессом, реализующим определенное средство в системе;
в этом случае ему будет разрешено в соответствии с его положе-
нием на дереве средств обслуживать вызовы средства.
10.2.2.2. Ресурсы, возможности и защита
Управление запросами ресурсов в системе SUE осуществляется
с помощью возможностей (см. разд. 7.2.). Возможность представ-
ляет собой 64-битовую запись, которая указывает доступность не-
которого ресурса процессу. Каждому процессу соответствует список
возможностей, определяющий долю ресурсов процесса, выделен-
ных его предками.
Каждая возможность имеет связанного с ней менеджера, кото-
рый в общем случае может быть или средством, первоначально по-
родившим данную возможность, или стержнем (см. следующий раз-
дел). Возможность может быть модифицирована либо явным обра-
зом, менеджером данной возможности, либо неявно, каким-либо
средством путем использования примитива «Закончить обработку
вызова средства».
Каждая возможность содержит поле, определяющее ее менед-
жера и набор признаков, от которых зависит допустимость сле-
дующих действий:
1) передать данную возможность вновь созданному сыну;
2) передать данную возможность при выполнении вызова сред-
ства;
3) оформить возможность после ее создания;
4) уничтожить возможность без уведомления менеджера.
Существуют три различных формата для возможностей: булев-
ский, числовой и частный. В зависимости от формата остальные
биты возможности (кроме спецификации менеджера и признаков)
интерпретируются следующим образом.
1. Булевский. Возможность понимается как маска, определяю-
щая ограниченный доступ к ресурсу. Например, в соответствии
с возможностью для файла один процесс может иметь доступ для
чтения и записи, а другой — доступ только для чтения.
2. Числовой. Возможность рассматривается как целое число.
Числовые возможности обычно используются для потребляемых
ресурсов, таких, как время центрального процессора или счетчик
количества неиспользованных операций ввода-вывода.
3. Частный. Возможность содержит информацию, понятную толь-
ко породившему ее процессу.
Возможности представляют собой аппарат, полезный как для
защиты, так и для управления ресурсами. Поскольку почти все ре-
сурсы в системе представлены как возможности, существует единый
метод создания возможностей, действий над ними и уничтожения
их, выраженные операциями над возможностями: создать возмож-*
ность, прочитать возможность и модифицировать возможность.
Возможности также защищены. При передаче информации о ре-
сурсах от одного процесса к другому (когда возможность являет-
ся параметром в вызове средства) в действительности передается
только номер гнезда возможности в списке возможностей (в терми-
нологии почтовых ящиков). Списки возможностей защищены от
процессов таким образом, что ни один процесс не может «подделать»
возможность. Процесс может информировать другой процесс о сво-
их правах доступа, передавая номер гнезда возможности; второй
процесс после этого может посмотреть содержимое, соответствую-
щее данному гнезду. Только стержень может изменять списки воз-
можностей, и такая ситуация, когда другие процессы могут сооб-
щить неправду о распределении своих ресурсов, исключается.
Возможности предоставляют также аппарат для учета исполь-
зования ресурсов. При создании процесса он получает от отца свою
первоначальную долю ресурсов через список возможностей. Про-
цесс несет ответственность за использование своих ресурсов, и он
может или использовать их сам, или передавать их сыновним про-
цессам. Если каждый процесс хранит записи о распределенных им
возможностях, то, просмотрев списки возможностей каждого про-
цесса, можно всегда произвести полный учет всех ресурсов.
10.2.2.3. Стержень
Процессы, операции для обеспечения средств и возможности не
встроены в аппаратуру IBM/360, а реализованы на ней первым уров-
нем программного обеспечения, называемым стержнем. Стер-
жень —это не процесс в смысле обеспечения средств, как показано
на рис. 10.2. Точнее, это программа, которая изменяет основную
машинную структуру IBM/360 таким образом, чтобы включить
элементарные операции по управлению процессами, прерываниями,
памятью, возможностями, средствами, периферийными устройства-
ми и часами реального времени. Представляемая стержнем вирту-
альная машина, которая включает набор непривилегированных
команд машины IBM/360 и примитивы стержня, и является той
машиной, с которой в действительности имеют дело процессы. Мож-
но считать, что стержень так модифицирует аппаратуру, чтобы по-
лучилась виртуальная машина, более удобная для программиро-
вания ядра системы SUE. Читателю рекомендуется сравнить эту
виртуальную машину с виртуальной машиной, определяемой микро-
программой «Венера».
Стержень выполняется в привилегированном режиме с блоки-
ровкой прерываний и нулевым ключом памяти (т. е. он имеет до-
ступ ко всей памяти). В действительности это единственная про-
граммная часть системы, обладающая какими-либо из указанных
привилегий. Стержень по существу использует всю машину без
ограничений. Следовательно, ни один процесс не может защитить
себя от стержня. Кроме того, стержень защищен от остальной
системы, так как ни одному процессу не разрешено работать с клю-
чом памяти, принадлежащей стержню. Отсюда следует, что ни один
процесс не может намеренно или неумышленно изменить стержень.
Стержень обеспечивает для остальной части ядра выполнение
семи функций.
1. Процессы. Стержень обеспечивает выполнение элементарных
операций по созданию, уничтожению, начальному запуску и пре-
кращению выполнения процессов. В стержне каждому процессу
соответствует дескриптор процесса и список возможностей. Дес-
криптор процесса может быть прочитан и изменен самим процес-
сом или его отцом. После того как процесс создан, он устанавли-
вается в пассивное состояние и может быть запущен в любое время
его отцом. После запуска процесс выполняется на своем собственном
виртуальном процессоре. Прерывания для процесса незаметны,
так как они обслуживаются стержнем. Процесс продолжает выпол-
няться (ему отводится время наравне с другими активными про-
цессами) до тех пор, пока его не прервут или он не будет задержан.
2. Задержки. Когда возникает какая-либо исключительная
ситуация, процесс, оказавшийся в этой ситуации, оказывается «за-
держанным». Задержка выражается в том, что данный процесс при-
останавливается и стержень посылает его отцу сообщение, уведом-
ляя о случившемся. Например, какой-либо процесс может ожидать
прерывания от периферийного устройства. Когда происходит дан-
ное прерывание, процесс задерживается стержнем. Затем его отец
принимает меры, чтобы уведомить о создавшейся ситуации данный
процесс (обычно с помощью изменения его дескриптора) и запус-
тить его вновь. Большинство задержек планируется заранее, в
каждом средстве имеются специальные процедуры для обслужи-
вания задержек.
3. Средства. Стержень реализует средства и три операции над
средствами, описанные в разд. 10.2.2.1.
4. Возможности. Дескриптору каждого процесса соответствует
полный список возможностей, которыми обладает данный процесс.
Операция создания возможности позволяет процессу породить но-
вую возможность, которая затем добавляется в его список возмож-
ностей. Операции «прочитать возможность» и «модифицировать воз-
можность» позволяют работать с существующими возможностями.
Возможности имеют формат, описанный в предыдущем разделе.
5. Управление памятью. Стержень обеспечивает три примитива
по управлению памятью. Операция установить ключ процесса уста-
навливает ключ защиты памяти, с которым выполняется данный
процесс. Естественно, процесс должен иметь соответствующую воз-
можность для работы с данным ключом. Операция установить ключ
памяти заново устанавливает ключ памяти для блока в 2К бай-
тов, который либо принадлежит процессу, либо доступен для него.
Операция создать системную область выделяет блок памяти для
дескрипторов процесса. Поскольку стержню требуется место для
дескриптора каждого процесса в системе, процессы должны обе-
спечивать стержень памятью для дескриптора каждого создаваемого
ими процесса. Блоки памяти (которые учтены в возможностях)
можно передавать от процесса к процессу с помощью операций
над возможностями.
6. Часы. Стержень управляет работой календарных часов, кото-
рые показывают дату и время дня, и часов времени выполнения, ко-
торые показывают время, использованное каждым процессом. Опре-
деленные привилегированные процессы могут запускать эти часы
и снимать показания.
7. Управление вводом-выводом. В стержне контролируются все
операции ввода-вывода на периферийных устройствах. Запускать
программы каналов и узнавать состояние каналов позволяют две
операции: запросить операцию ввода-вывода и запросить состояние
ввода-вывода. Детали этих операций, которые сильно зависят от
аппаратуры IBM/360, выходят за рамки данного описания.
10.2.3. Функции, выполняемые системой SUE
В разделе 10.2.2 былописан первый уровень программного обес-
печения системы SUE, называемый стержнем. Используя виртуаль-
ную машину стержня, система семи асинхронных процессов (рис.
10.2) обеспечивает основное множество средств ядра. Обзор этих
процессов, представленный в данном разделе, составляет краткое
описание услуг, предоставляемых ядром системы SUE.
10.2.3Л. Родоначальник
Это средство располагается в корне генеалогического дерева
системы SUE. Родоначальник обслуживает задержки для системы
управления каналами ввода-вывода (так как он является отцом
этого процесса) и, кроме того, реализует работу основного опера-
торского терминала, называемого главной консолью. Все процессы
имеют возможность «общаться» с этой консолью оператора при по-
мощи вызова средства, так как каждый процесс является потомком
родоначальника.
10.2.3.2. Система управления каналами ввода-вывода
Система управления каналами ввода-вывода, вторая важная
компонента генеалогического дерева, выполняет функцию созда-
ния виртуальных устройств управления аппаратурой ввода-выво-
да. Это значит, что задержки, возникающие в связи с занятостью
управляющих устройств, ошибками в каналах или незапланиро-
ванными прерываниями, оказываются незаметными для пользова-
телей данного средства. Этим процессом выполняется операция,
называемая программой работы канала, которая запускает про-
грамму данного канала с помощью операции стержня запросить
ввод-вывод.
Программы канала обычно требуют много времени для своего
выполнения, поэтому для обращения к средству «выполнить про-
грамму канала» процессу будет удобно породить буферный про-
цесс, если сам он за это время может выполнить какую-либо полез-
ную работу.
10.2.3.3. Дисковая система ввода-вывода
Дисковая система ввода-вывода реализует простую систему
управления файлами и интерфейс для чужих (т. е. размеченных не
по правилам системы SUE) дисков. Все запросы на работу дисков
и для стандартных файлов системы SUE, и для специально органи-
зованных чужих томов должны проходить через данный процесс.
Когда какой-либо процесс желает получить доступ к файлу (т. е.
читать или писать), он должен предъявить три возможности. Пер-
вая возможность доказывает владение ключом памяти, соответст-
вующим той области, куда будет происходить чтение или откуда
будет вестись запись. Вторая возможность удостоверяет процесс
как законного пользователя данного файла. Третья возможность
представляет счетчик числа дисковых операций, разрешенных про-
цессу; с каждой выполненной операцией ввода-вывода он умень-
шается на единицу.
Все файлы в системе SUE составлены из смежных блоков по 2К
байтов. Операции чтения и записи на дисках выполняются всегда
над группой таких записей одинаковой длины. Процесс, владею-
щий файлом, может создать новую возможность для группы смеж-
ных записей в пределах области своего файла. Эта операция над
файлом, называемая «образованием подмножества», позволяет про-
цессу использовать часть своего файла совместно с каким-либо по-
томком. Дисковой системе не нужно, однако, вести учет того, кому
принадлежит каждая часть каждого диска. Если процесс предъяв-
ляет законную возможность на работу с определенным блоком за-
писей какого-либо файла, ему разрешается доступ к этим записям.
Таким образом, на сам процесс, разбивший свой файл на подмно-
жества, возлагается обязанность знать, кто имеет права доступа к
файлу.
Те процессы, которые хотят организовать свои диски специаль-
ным образом, должны назвать себя дисковой системе. Затем диско-
вая система образует возможность, которая позволяет такому про-
цессу писать на его диск по формату, отличному от принятого в
системе SUE.
И наконец, дисковая система ввода-вывода обеспечивает сред-
ство для запуска и остановки логических устройств. Эти команды,
которые в первую очередь используются менеджером томов, воз-
буждают и отключают дисковые устройства.
10.2.3.4. Система управления пишущей машинкой
Система управления пишущей машинкой обеспечивает для про-
цессов интерфейс с внешним миром через терминалы типа пишу-
щих машинок. Начиная работу за терминалом, пользователь зада-
ет имя процесса, с которым он желает связаться. Процесс для свя-
зи с терминалом выдает системе управления пишущей машинкой
запрос средства, определяя в нем имя, под которым ожидается
обращение к данному процессу. Тогда первая пишущая машинка,
с которой поступит это имя, будет отдана данному процессу и тем
самым будет выполнен вызов средства. Когда процессу дается тер-
минал для обмена сообщениями, он обычно порождает два
буферных процесса. Один из них передает сообщения на тер-
минал и от терминала, а другой посылает данному процессу сооб-
щение, когда поступает сигнал «внимание». В действительности
ввод-вывод инициируется самой системой управления пишущей
машинкой.
10.2.3.5. Менеджер томов
Менеджер томов контролирует установку и снятие томов. Воз-
буждая вызов средства — менеджер томов, процесс может попро-
сить, чтобы был установлен дисковый пакет. Процесс должен
представить возможности, доказывающие его право на владение
запрошенным томом и логическим дисководом, на который его поста-
вят. Каждый том представлен уникальным именем из шести сим-
волов, которое переводится менеджером томов в однобайтовый но-
мер. Этот номер служит внутренним представлением метки тома.
После проверки возможностей вызывающего процесса менеджер
томов посылает соответствующему терминалу типа пишущей машин-
ки (т. е. консоли оператора) сообщение об установке данного тома.
После установки тома производится вызов средства дисковой сис-
темы ввода-вывода с запросом на запуск устройства. Снимаются то-
ма аналогичным образом.
10.2.3.6. Менеджер специальных ситуаций
Менеджер специальных ситуаций является связующим звеном
между родоначальником и несколькими внешними устройствами.
По команде от родоначальника менеджер специальных ситуаций
устанавливает контакт с терминалом типа пишущей машинки (че-
рез систему управления пишущей машинкой), который объявил
себя главной консолью. В случае некоторых серьезных системных
ошибок родоначальник перед снятием системы может выдать менед-
жеру специальных ситуаций запрос на запись некоторых данных
на диск. Само собой разумеется, что таким образом может быть за-
писана и учетная информация.
Заметим, что этот путь связи (т. е. от родоначальника к менед-
жеру специальных ситуаций) является нарушением структуры
системы, так как, вообще говоря, процессу не разрешается поль-
зоваться услугами своих потомков. В системе имеется на самом деле
только одно такое нарушение. Оно вызвано понятными причина-
ми. Находясь в корне генеалогического дерева, родоначальник мо-
жет знать о системе больше, чем любой другой процесс. Однако,
чтобы использовать уникальность своей позиции, он должен иметь
связь с дисковой системой ввода-вывода и системой управления
пишущей машинкой, которые обе находятся ниже его на генеалоги-
ческом дереве. Нарушая структуру системы, менеджер специаль-
ных ситуаций создает необходимые пути от родоначальника к ука-
занным процессам. Эта аномалия в структуре требует особой осто-
рожности, чтобы не допустить таких тупиковых ситуаций, когда
родоначальник вызывает менеджера специальных ситуаций, а он в
свою очередь вызывает родоначальника (т. е. оба процесса попадут в
условия постоянного ожидания).
10.2.3.7. Менеджер учета в ядре
Менеджер учета в ядре наблюдает за работой подчиненных опе-
рационных систем, которые находятся под управлением ядра систе-
мы SUE (например, пакетной системы, интерактивной системы или
текстового редактора). Две его основные функции заключаются в
том, чтобы распределить системные ресурсы между активными поль-
зователями и реализовать работу консоли ядра, которая служит
операторской консолью для подчиненных операционных систем.
Чтобы запустить подчиненную операционную систему, поль-
зователь консоли занимает телетайп и просит у менеджера учета
в ядре позволения начать работу. После установления связи поль-
зователь консоли ядра просит выделить его системе определенную
совокупность ресурсов (например, память, процессорное время,
дисководы). Если эти требования не превышают максимума, поло-
женного данной подсистеме, и если указанные ресурсы в дан-
ный момент доступны, подсистема начинает работать. В противном
случае менеджер учета в ядре извещает консоль ядра о препятстви-
ях в выполнении запроса и просит уменьшить количество запраши-
ваемых ресурсов.
После запуска консоль ядра, на которой работает пользователь,
становится главной операторской консолью для данной подчинен-
ной операционной системы. Пользователь может получить сведе-
ния о состоянии своей системы, запросить изменения распределения
ресурсов, связаться с системой и даже снять систему. Использова-
ние ресурсов подчиненной операционной системой фиксируется на
дисковых файлах менеджером учета в ядре и позднее может быть
использовано при оформлении счетов.
Ниже менеджера учета в ядре на генеалогическом дереве сле-
довало бы иметь средство, управляющее такими периферийными
устройствами, как устройства ввода перфокарт и построчно печа-
тающие устройства. Управление периферийными устройствами не
включено в ядро системы SUE, но оно, очевидно, должно быть пер-
вым средством, находящимся на генеалогическом дереве ниже ядра.
10.3. Операционная система „Венера"
Операционная система «Венера» — это интерактивная муль-
типрограммная система, разработанная в корпорации MITRE для
малой медленной микропрограммной машины Interdata 3. Машина
«Венера», т. е. машина Interdata 3 с микропрограммой «Венера»,
имеет страничную организацию и допускает сегментирование. Каж-
дый сегмент, содержащий процедуру или данные, доступен любому
пользователю в системе (как правило, работают три пользователя).
Перед началом работы пользователь может ввести в систему одну или
несколько колод карт, чтобы они хранились в виде сегментов. Затем
пользователь начинает работу на терминале телетайпного типа.
По командам, выданным с терминала, могут читаться по сегментам
файлы с магнитной ленты. По другим командам производится выпол-
нение одного или нескольких процедурных сегментов. Выполнение
процедуры может идти в режиме отладки. Для проверки программы
пользователь может определить в ней «точку прерывания»; когда
программа доходит до точки прерывания, управление передается
подпрограмме отладки и пользователь может в интерактивном ре-
жиме анализировать состояние своей программы. Результаты за-
конченных вычислений запоминаются в выводном сегменте, кото-
рый затем может быть выдан на построчно печатающее устройство
или сохранен на магнитной ленте.
Главной целью проектирования системы «Венера» было пока-
зать, что «хорошая» аппаратура может значительно упростить соз-
дание системы программного обеспечения. В соответствии с этой
установкой допускалось влияние машинной структуры на структу-
ру системы. В самом деле, поскольку данная машина микропрограм-
мная, разработчики могли формировать характеристики машины
в соответствии со своими нуждами. Имея чистую аппаратную
базу, они добавили уровни виртуальных машин для получения хо-
рошо организованной системы с небольшим числом ошибок.
10.3. L Аппаратура
Interdata 3 — это малая микропрограммная машина с микро-
памятью на 2000 команд. Система «Венера» работает с конфигура-
цией, включающей 64/С байтов оперативной памяти, два лентопро-
тяжных устройства, диск на половину мегабайта (для реализации
страничной системы), несколько телетайпов, построчно печата-
ющее устройство и устройство ввода с перфокарт. Имеются аппа-
ратные каналы с доступом к оперативной памяти — один для лен-
топротяжных устройств и один для диска. Каналы для других
устройств моделируются микропрограммой. В промежутках между
циклами команд микропрограмма обслуживает любое устройство,
требующее внимания (включая лентопротяжные устройства и диск).
Программное обеспечение, следовательно, освобождено от особен-
ностей работы в режиме реального времени, которые, как правило,
связаны е обслуживанием прерываний ввода-вывода. Интерфейс
каналов описан далее в разд. 10.3.4.
Так как окончание работы внешних устройств не вызывает
прерываний, нижние уровни системы «Венера» освобождены от
сложной кропотливой работы по соответствующему учету. Если в
системах имеются прерывания ввода-вывода, иногда бывает трудно
определить, выполнение какого именно ввода-вывода вызвало пре-
рывание. Если, например, в такой системе появилось прерывание
от диска, то «интерпретатор прерываний», входящий в програм-
мное обеспечение, должен выделить процесс, обратившийся к диску.
В случае если диском пользуются несколько процессов, это может
оказаться нелегким делом. Такого рода проблемы не встречаются
в системе «Венера». Все прерывания связаны с текущим процессом
и возникают при таких ситуациях, как арифметическое перепол-
нение или некорректное выполнение команды. Таким образом, в
системе «Венера» никогда не бывает неопределенностей, связанных
с выяснением того, какой процесс вызвал прерывание.
10.3.2. Процессы
Микропрограмма системы «Венера» допускает 16 процессов.
Каждый процесс определяется резидентной рабочей областью в
оперативной памяти и адресным пространством, охватывающим
каждый сегмент в машине. Рабочая область содержит место для об-
щих регистров, счетчика программы и другой информации, свя-
занной с процессом (например, ссылки для семафорных очередей
и программно задаваемых приоритетов).
Процессы общаются друг с другом с помощью семафоров.
С каждым семафором связан головной элемент, который состоит из
значения семафора и указателя на первый процесс из списка бло-
кированных этим семафором процессов. Блокированные данным
семафором процессы через свои рабочие области связаны односто-
ронней связью с головным элементом семафора. Когда процесс
выполняет над семафором P-операцию, микропрограмма уменьша-
ет значение семафора на единицу. Если в результате получается
неотрицательное значение, процесс продолжается; в противном
случае его выполнение приостанавливается и он добавляется в
очередь соответствующего семафора. V-операция над семафором
освобождает один процесс; выбирается из очереди тот процесс
данного семафора, который имеет наивысший приоритет. Если
имеется несколько процессов с наивысшим приоритетом, то выби-
рается тот из них, который дольше всех ждет. Процесс, не состоя-
щий ни в одной из очередей семафоров, является или готовым к
выполнению, или текущим. Готовые для выполнения процессы
образуют «очередь готовности», которая управляется так же, как
очереди семафоров. Таким образом, текущий процесс всегда имеет
приоритет, по меньшей мере, такой же высокий, как все процессы
в очереди готовности, так как освобожденный в результате Е-опе-
рации процесс претендует на то, чтобы стать текущим. ,
Семафоры используются процессами для синхронизации друг
с другом, для синхронизации с устройствами ввода-вывода и для
обмена сообщениями через очереди. Последние два применения
описаны в последующих разделах.
10.3.3. Виртуальная память
Машина «Венера» имеет сегментированную память со странич-
ной структурой, реализованной при помощи микрокоманд. Размер
страниц — 256 байтов, сегмент может содержать до 256 страниц.
Адресные ссылки вычисляются с помощью одной из восьми пар
регистров; регистр сегмента содержит имя сегмента, а соответ-
ствующий ему общий регистр содержит номер страницы и смещение
внутри страницы. Каждый регистр сегмента имеет также «рас-
ширение»; расширение представляет собой регистр, который отоб-
ражает номер страницы из общего регистра в адрес памяти (т. е.
адрес физического места в памяти, где располагается данная стра-
ница). Для получения доступа к слову из памяти программа ссы-
лается только на общий регистр. Чтобы определить, какой сегмент
содержит данную страницу, микропрограмма использует соответ-
ствующий регистр сегмента и расширение. Программа сама должна
следить за тем, чтобы в нужный регистр сегмента было загружено
правильное имя сегмента.
Вычисление значений расширения регистра сегмента и меха-
низм поддержания соответствия страниц обеспечиваются микро-
программой. Если нужно через общий регистр получить доступ к
какому-либо слову, микропрограмма анализирует расширение со-
ответствующего регистра сегмента. Если расширение ссылается
на ту же страницу, что и общий регистр, тогда страница находится
в памяти и ее адрес имеется в расширении. Если расширение не
соответствует странице из общего регистра, то микропрограмма
должна найти нужную страницу. Сначала поиск ведется по таб-
лице страниц в памяти, которая содержит список всех страниц,
находящихся в данный момент в памяти. Если данная страница
имеется в памяти, то расширение регистра сегмента подправляется
таким образом, чтобы оно указывало на нужную страницу, и про-
грамма может продолжать работать. Если страницы нет в памяти,
то вызывается программный интерпретатор поддержания соответ-
ствия страниц; он находит на диске нужную страницу, записывает
ее куда-либо в память, подправляет таблицу страниц в памяти
и возвращает управление в микропрограмму после точки вызова.
Заметим, что интерпретатор поддержания соответствия страниц
является подпрограммой микропрограммы и должен, следователь-
но, рассматриваться как часть машины «Венера».
Замещение страниц в машине «Венера» реализовано по правилу
LRU: «удаляется страница, к которой дольше всех не было обра-
щения». Каждая страница, связанная с некоторым расширением
регистра сегмента, может быть зафиксирована в памяти. Кроме
того, для процессов и таких элементов операционной системы,
как таблица страниц в памяти, рабочие области процессов и ин-
терпретатор поддержания соответствия страниц, может быть за-
фиксировано в памяти и несколько страниц. Все остальные стра-
ницы образуют список «по возрасту» и являются кандидатами на
замещение. В конец указанного списка страница добавляется
тогда, когда на нее больше не имеется ссылок ни в одном расшире-
нии. Таким образом, в списке по возрасту страницы упорядочены
в соответствии с длиной интервала времени, прошедшего с момента
последнего обращения к ним. Интерпретатор поддержания соот-
ветствия страниц удаляет верхнюю страницу из списка по возрасту
и использует занимаемое ею физическое место в памяти для новой
страницы. Затем перед окончанием своей работы интерпретатор
поддержания соответствия страниц подправляет расширение ре-
гистра сегмента и таблицу страниц в памяти.
Процессы и виртуальная память реализованы микропрограм-
мой. Другими словами, машина Interdata 3 не имеет встроенной
аппаратуры страничного обмена и мультипрограммирования. Сле-
довательно, все решения по организации памяти и процессов были
приняты разработчиками на этапе написания микропрограмм; по
существу микропрограммное оборудование позволило им пост-
роить свою собственную машину. Там, где наиболее важно было
получить высокую скорость, соответствующие функции реализова-
ли микропрограммой (например, вычисление адресов физической
памяти по адресам виртуальной памяти). Там, где было желатель-
но получить наибольшую гибкость, функции включали в програм-
мное обеспечение (например, интерпретатор поддержания соответ-
ствия страниц). Проектируя оборудование, разработчики системы
«Венера» фактически выбирали спецификации для своей виртуаль-
ной машины самого нижнего уровня.
Сравните построенную с помощью микропрограммирования ма-
шину «Венера» с двумя самыми нижними уровнями системы THE.
Система «Венера» реализует независимые совместно работающие
процессы и виртуальную память полуаппаратным путем, в то же
время система THE реализует эти же функции чисто программным
путем. На самом деле нет никаких причин, по которым данные
функции не могли бы быть встроены непосредственно в аппара-
туру. Если это было бы сделано, мы бы имели реальную машину,
соответствующую первому уровню виртуальной машины системы
THE.
10.3.4. Расширения микропрограммы
Имеется три программных придатка, которые увеличивают
гибкость микропрограммы «Венера»: словари, очереди и распоря-
дитель.
10.3.4.1, Словари
Сегменты идентифицируются уникальными 15-битовыми име-
нами, которые, с точки зрения пользователя, не особенно удобны.
Поэтому программное обеспечение системы «Венера» включает на-
бор словарей, которые отображают внешние, данные пользовате-
лями имена сегментов во внутренние 15-битовые имена. Каждое
внешнее имя определяет словарь и имя внутри словаря. Централь-
ный словарь отображает внешние имена словарей в их внутренние
имена. Таким образом, этот двухуровневый механизм внешнего
именования облегчает пользователям работу с общими сегмента-
ми, избавляя их от необходимости помнить внутренние идентифи-
каторы сегментов.
10.3.4.2. Очереди
Механизм синхронизации процессов реализуется с помощью
семафоров. Процессы связываются друг с другом, передавая сооб-
щения через совокупность очередей. Доступ к этим очередям воз-
можен только посредством системных процедур, которые использу-
ют семафоры, гарантируя защиту от некорректного обращения к
очереди, когда предыдущее обращение еще не завершено.
10.3.4.3. Распорядитель
Число процессов в системе «Венера» ограничено количеством
рабочих областей процессов, которые могут находиться в опера-
тивной памяти. Если принять максимальное число пользователь-
ских процессов равным шести, для системы остается только десять
процессов, что явно не достаточно. В связи с этим в систему вклю-
чена простая процедура, называемая распорядителем, которая
позволяет нескольким процессам использовать одну виртуальную
машину (т. е. рабочую область). Когда появляется событие, которое
влияет на использование виртуальной машины распорядителя,
все процессы, совместно использующие данную виртуальную ма-
шину, опрашиваются, пока один из них не признает событие. Выбор
процессов, которые должны вместе работать на виртуальной ма-
шине распорядителя, основывается на соображениях глобальной
эффективности системы.
10.3.5. Система ввода-вывода
Система «Венера» обеспечивает управление ресурсами без тупи-
ков для всех устройств ввода-вывода, а также для центрального
процессора, диска и системных сегментов. Один из наиболее удач-
ных примеров применения подхода, связанного с уровнями, для
10*
управления ресурсами в системе «Венера» — это система ввода-
вывода. В связи с этим, а также поскольку система ввода-вывода —
основная компонента операционной системы, она описывается
здесь подробно.
Система ввода-вывода «Венеры» организована в виде последо-
вательности виртуальных машин (рис. 10.3). На нулевом уровне
находится канал устройства, реализованный микропрограммой.
Канал получает команды на передачу данных из буфера в опера-
тивной памяти на указанное устройство и наоборот. Если устройство
представляет собой терминал типа телетайпа, построчно печатаю-
щее устройство или устройство ввода перфокарт, то микропрограм-
ма фактически выполняет передачу, перемещая данные по одному
байту за раз. Передача данных на ленту и диск и обратно осущест-
вляется аппаратными каналами. Окончание операций ввода-выво-
да, однако, на любом устройстве, включая ленты и диск, воспри-
нимается микропрограммным каналом, который сигнализирует о
завершении команды ввода-вывода, выполняя над семафором,
связанным с вызвавшим действие процессом, У-операцию.
На 1-м уровне создаются процессы-яоктроллерв/ для лентопро-
тяжных устройств, устройств ввода перфокарт, печати и для каж-
дого телетайпа (диск отдан подсистеме виртуальной памяти). Конт-
роллеры работают на виртуальной машине нулевого уровня, улуч-
шая для своих пользователей характеристики устройств. В то время
как пользователи нулевого уровня сами должны обеспечивать в опе-
ративной памяти буферы для передач данных, контроллеры допус-
кают буферы в сегментах виртуальной памяти. Это значит, что конт-
роллеры берут на себя ответственность за перепись данных с сег-
ментного буфера на буфер в оперативной памяти. Кроме того, длина
передаваемой информации фиксируется и равна длине одной записи;
причем длина записи зависит от устройства (например, одна перфо-
карта или одна строка). Контроллер может быть возбужден в любой
момент независимо от того, свободно ли устройство. Как только
устройство станет доступным, контроллер будет выполнять команду
ввода-вывода. Когда требуемая передача завершается, контроллер
посылает сигнал вызвавшему операцию процессу через семафор,
который был указан в данной команде.
На 2-м уровне реализована процедура, называемая интерпрета-
тором телетайпных запросов. Интерпретатор телетайпных запросов
обеспечивает интерфейс между пользовательскими и системными
процессами, с одной стороны, и контроллерами телетайпов — с дру-
гой. Процессы ввода-вывода более высоких уровней могут исполь-
зовать интерпретатор телетайпных запросов для связи с телетайп-
ными терминалами.
3-й уровень состоит из процессов-драйверов, соответствующих
устройствам ввода перфокарт, печатающим и лентопротяжным уст-
ройствам. Драйвер, который для выполнения ввода-вывода исполь-
Рис. 10.3. Система ввода-вывода системы «Венера».
зует команды контроллера, представляет собой виртуальное устрой-
ство, которое переписывает один сегмент за одно обращение к нему.
Драйвер объединяет буферы ввода в один сегмент и разбивает сег-
менты вывода на части такого размера, которые отвечают требовани-
ям контроллеров. Драйвер устройства ввода перфокарт строит сег-
менты из образов карт до тех пор, пока не будут исчерпаны карты
в кармане читающего устройства. Для получения законченного
сегмента необходима синхронизация. Драйвер устройства печати
должен возбуждаться командой процесса «напечатать сегмент». Он не
извещает своего пользователя о завершении печати. Драйвер ленто-
протяжного устройства возбуждается из процесса по команде «чи-
тать/писать сегмент». Процесс, выдавший команду, должен ждать
завершения операции чтения/записи.
4-й уровень состоит из процедур-интерпретаторов запросов для
каждого драйвера. Интерпретатор упрощает интерфейс между драй-
верами и процессами пользователей, помогая в построении сегментов
и синхронизации последовательностей команд (например, для драй-
вера лентопротяжного устройства).
Система ввода-вывода «Венеры» — это хороший пример примене-
ния предложенного Дейкстрой подхода, опирающегося на уровни
абстракции. Каждый уровень в системе ввода-вывода абстрагиру-
ется от тех деталей, которые не являются необходимыми, и обеспе-
чивает более удобную виртуальную машину для процессов пользо-
вателя. Виртуальная машина, составляющая нижний уровень
системы, т. е. сама машина «Венера», имеет такие полезные инстру-
менты, как операции над семафорами и сегментно-страничная па-
мять, которые используются для реализации системы ввода-вывода
на всех уровнях.
10.4. Другие системы
В литературе описано много других систем. В этом разделе упо-
минаются только несколько таких систем, которые могут дать за-
интересованному читателю представление о имеющихся направлени-
ях.
Операционные системы THE [Дейкстра, 1968 Ь] и RC4000 [Бринч
Хансен, 1970] представляют собой в высшей степени структуриро-
ванные системы, разработанные для малых (и довольно необычных)
машин. Обе системы были новыми по своим принципам и привлекли
большое внимание как примеры того, как должны строиться опера-
ционные системы.
Система MULTICS [Органик, 1972]—это сложная вычислитель-
ная система широкого назначения, разработанная в Массачусетском
технологическом институте для машин GE Honeywell. Эта система
основана на сложной схеме сегментно-страничной адресации, кото-
рая обеспечивает динамичное и гибкое разделение времени.
Хотя именно такие системы считаются прекрасным материалом
для педагогических целей, они не характерны для операционных си-
стем, наиболее распространенных в реальном мире. Сэйерс (1971]
и Хоар и Перро [1972] описали несколько практически пригодных
систем для распространенных машин. В качестве первого шага для
понимания таких систем читатель должен попытаться получить ин-
формацию о той системе, с которой ему приходится, как правило,
иметь дело. Знание внешних характеристик системы часто помогает
понять и ее внутренние механизмы.
Большинство из этих систем было реализовано до того, как струк-
турный подход серьезно повлиял на проектирование систем. Эти
системы нелегко понять и иногда трудно использовать. Редко можно
найти системы, столь же элегантные по своему исполнению, как
системы SUE или «Венера». Однако практически используемые
системы выполняют много полезной работы для огромной массы
людей.
Есть люди, которые считают, что системы могут быть либо эле-
гантными, либо практичными, но не могут обладать обоими качест-
вами. Мы не согласны с этим мнением: оно носит пораженческий
характер. Системы можно проектировать так, чтобы они были понят-
ны и имели хорошую структуру без какого-либо ущерба для их
достоинств в смысле практичности.
Задания
10.1. Проведите тщательное изучение существующих операционных
систем. Ниже даны примеры систем, которые надо изучить.
Фирма IBM: OS/360 (MFT/MVT), DOS/360, 1800 Multiprogram-
ming Executive, OS/VS, VM/370
Фирма DEC: PDP-10 Time Sharing System, PDP-11 DOS System,
PDP-11 RSX-11D, PDP-11 MUMPS, PDP-11 RSTS,
PDP-8 Time Sharing System
Фирма CDC: 6400/6500/6600 Scope 3 Operating System, CDC 3300/
3500 Master Operating System
Univac 1108 Exec 8 Operating System
Honeywell 600 system, Honeywell 200 Mod 4 Operating System
MULTICS System
Compatible Time Sharing System (CTSS)
Фирма XDS: Sigma 2 Real-Time Batch Monitor, Sigma 5/7 Batch
Time Sharing Monitor
Фирма Burroughs: B5500 system, B6500 Master Control Program
Hewlett Packard 3000 Operating System
ILLIAC IV Operating System
Michigan Terminal System
GAL 6000 Time Sharing System
10.2. Компоненты аппаратуры становятся менее дорогими и более
мощными. Некоторые из функций операционной системы, реализу-
емые, как правило, программным обеспечением, могут быть возло-
жены на аппаратуру. Какие функции операционной системы, по ва-
шему мнению, больше всего подходят для аппаратной реализации?
Есть ли причины, по которым всю операционную систему не следует
включать в аппаратуру?
10.3. Подготовьте обзор использования вычислительных машин
в банковских системах.
10.4. Проведите тщательное изучение системы резервирования авиа-
билетов на примере следующих систем: American Airlines SABRE
system, Air Canada Reservec system, BOAC reservation system
(BOADICEA), United Airlines reservation system, IBM PARS/
10.5. Подготовьте сравнительный обзор операционных систем для
мини-машин.
10.6. Терминология в операционных системах сильно зависит от
местных условий и организации. Подготовьте словарь терминов,
имеющихся в справочных руководствах по крайней мере трех изго-
товителей или главных пользователей вычислительного оборудова-
ния. Установите достаточно точно все варианты наименований для
общеупотребительных понятий, например для процессов.
Приложение I
СТРУКТУРЫ ДАННЫХ
Структура данных — это группа из одного или более элементов
данных, которые структурно связаны между собой. Работа со струк-
турами данных состоит из двух основных действий: создания и под-
держания, Последнее понятие включает такие операции, как вклю-
чение элементов в структуру, удаление элементов из структуры и
локализацию элементов в структуре. Различные приложения делают
упор на какую-либо одну из перечисленных операций; в связи с
этим существует большое разнообразие структур данных. В каждом
таком приложении самую важную операцию стремятся реализовать
наиболее эффективно по занимаемой памяти или по времени выпол-
нения.
В операционных системах широко распространено использова-
ние сложных структур данных. В этой главе кратко описаны неко-
торые основные принципы хранения и доступа для информации,
организованной в структуру. Данное изложение не предназначено
служить введением в структуры данных, а скорее представляет собой
обзор материала, необходимого для понимания книги. Неподготов-
ленному читателю рекомендуем обратиться к какому-либо хорошему
учебному пособию по структурам данных, например к книге Кнута
[1968].
1.1. Определения понятий
Назовем элементом логическую единицу информации и под
списком будем понимать линейно упорядоченную последователь-
ность элементов (е(1), е(2), ..., е(/г)]. Другими словами, пара эле-
ментов списка e(k) и e(k-\-V) такова, что элемент e(k) предшествует
элементу е(Л+1), а элемент е(£+1) следует за элементом е(й). Списки
могут формироваться во всех случаях, когда возникает потребность
в таблицах упорядоченной информации (например, список блоков
свободной памяти, список активных заданий, список файлов
пользователя).
Налагая ограничения на способы добавления и удаления эле-
ментов списка, можно определять новые структуры. Так, например,
стек определяется как список, в котором включения и удаления
элементов производятся с одного конца. Очередь — это список, в ко-
тором включения и удаления делаются на противоположных концах.
1.2. Последовательное размещение списков
Элементы списка могут храниться в последовательных ячейках
памяти. Пусть выражение MEMORY(y) означает адрес физической
памяти, где располагается элемент у. Рассмотрим список х, первому
элементу которого соответствует некоторый базовый адрес (этот
базовый адрес можно записать как MEMORY(x(0)). Если каждый
элемент занимает фиксированное число ячеек L, то последовательное
размещение характеризуется соотношением
MEMORY (х (4 + 1)) = MEMORY (х (0) + L, i > 1
Предположим, что в памяти имеется четыре списка Л, В С и Z),
которые размещены последовательным способом в областях с теми
же именами. На рис. 1.1 область В почти доходит до границы области
С, хотя справа от областей С и D имеется много неиспользованных
ячеек. В такой ситуации для размещения потенциально растущих
списков можно воспользоваться двумя простыми методами.
Первый метод, называемый уплотнением, заключается в пере-
размещении некоторых меньших списков для того, чтобы освободить
дополнительное место для больших. Применяя уплотнение, можно,
как показано на рис. 1.2, расширить свободное место для списка В,
Дополнительное свободное место для списка В появилось в ре-
зультате размещения списков С и D в области с большими адресами.
Рис. 1.1. Схема распределения памяти I. (Штриховкой отмечены используемые
области памяти.)
Рис. 1.2. Схема распределения памяти II.
Рис. 1.3. Схема распределения памяти III. (Стрелка указывает на продолжение
области списка В.)
Второй метод, называемый косвенной адресацией, включает ис-
пользование связок1). Связка — это элемент памяти, который со-
держит адрес другого слова памяти. Если в конец заполненной об-
ласти поместить связку, указывающую на свободное место, то тем
самым можно без перераспределения памяти дать большому списку
дополнительное место для последующего увеличения. На рис. 1.3.
область В из рис. 1.1 расширена с помощью косвенной адресации.
Если для заполнения участков памяти используется косвенная ад-
ресация, то последовательное размещение применяется только в
смежных областях в пределах списка.
1.3. Связные списки
В связном (одностороннем) списке каждый элемент списка содер-
жит две составляющие: информацию, относящуюся к данному эле-
менту (т. е. ДАННЫЕ), и связку, указывающую на следующий эле-
мент списка (т. е. УКАЗАТЕЛЬ). На рис. 1.4 показан связный спи-
сок из четырех элементов. На первый элемент списка указывает
(а)
ДАННЫЕ УКАЗАТЕЛЬ
Рис. 1.4. (а) Односторонний связный список; каждый элемент имеет вид (Ь).
специальный элемент, называемый головой списка. Последний эле-
мент имеет указатель, равный значению «пусто», означающий конец
списка. Поскольку логическая структура списка не зависит от дейст-
вительных адресов ячеек памяти, связки на рисунках указываются
не адресами соответствующих элементов, а стрелками.
Связные списки могут быть также двусторонними. Элемент х яв-
ляется двусторонним, если он имеет два указателя: один указывает
на элемент слева от данного элемента х, а другой — на элемент спра-
х) В оригинале «link». Вместо термина «связка» обычно употребляется тер-
мин «ссылка».— Прим, перев.
(Ь)
ЛЕВЫЙ УКАЗАТЕЛЬ ДАННЫЕ ПРАВЫЙ УКАЗАТЕЛЬ
Рис. 1.5. (а) Двусторонний связный список; каждый элемент имеет вид (Ь).
ва от элемента х. Двусторонний связный список из трех элемен-
тов показан на рис. 1.5.
Двусторонний связный список (из-за дополнительного указате-
ля) требует на 50% больше памяти, чем соответствующий односто-
ронний список; однако в двустороннем списке упрощается включение
элементов в список и удаление элементов из списка. Имея лишь ука-
затель на какой-либо элемент, можно легко удалить данный эле-
мент из двустороннего связного списка, так как известен левый ука-
затель от этого элемента. В одностороннем связном списке нужно
просматривать список с начала, пока не встретится элемент с указа-
телем на тот элемент, который надо удалить.
В циклическом списке элементы образуют замкнутую структуру;
последний элемент циклического списка указывает на первый. До-
бавляя в элементы списка дополнительные поля связок, можно полу-
чить более сложные структуры данных. Эти многосвязные списки
можно строить на основе произвольных графических структур (на-
пример, на основе циклов, деревьев, сетей).
1.4. Управление связными списками
Для любой схемы управления связными списками нужна опера-
ция, которая получает из памяти неиспользуемые элементы. Реали-
зация этой операции часто основывается на применении односторон-
него связного списка неиспользуемых элементов, так называемого
свободного списка, на который указывает некоторый головной эле-
мент. Добавление элементов в свободный список происходит в основ-
ном двумя способами.
1.4.1. Управление, зависящее от пользователя
В этой схеме пользователи сами должны возвращать в свободный
список те элементы, которые больше не нужны. Возвратить элемент
х в свободный список можно, например, следующим образом: ус-
та повить УКАЗАТЕЛЬ элемента х так, чтобы он указывал на пер-
вый элемент свободного списка, и подправить головной элемент сво-
бодного списка так, чтобы он указывал на элемент х. После этого
элемент х становится новым первым элементом свободного списка.
Свободный список можно завести до начала выполнения программы,
установив в памяти соответствующие связки; головной элемент сво-
бодного списка должен указывать на первый элемент памяти, а в по-
следнем элементе УКАЗАТЕЛЬ должен содержать «пусто». Однако,
если память достаточно велика, эта процедура может потребовать
много времени. Другой способ состоит в том, чтобы отграничить
память, из которой могут выбираться свободные элементы. Первое'
время элементы основного списка размещаются последовательно
до тех пор, пока не будет достигнута граница области. Использован-
ные (ненужные) элементы отдаются в свободный список, который
прежде был пустым. Когда первоначальное размещение до границы
исчерпывает свои возможности, начинается управление с помощью
свободного списка. Этот способ находит применение и в методике,
описываемой ниже.
L4.2. Системное управление
Программиста можно освободить от обязанности явным образом
возвращать неиспользуемые элементы в свободный список; для этого
нужно написать служебную программу, которая обрабатывала бы
удаляемые элементы. Здесь возможны два варианта.
Первый вариант — это счетчики использования, или счетчики
ссылок. В каждый элемент х включается новое поле, в котором хра-
нится счетчик числа других элементов, содержащих ссылки на эле-
мент х (т. е. счетчик показывает, сколько других связок указывают
на элемент х). По мере добавления элементов в систему и удаления
из системы счетчик ссылок постоянно подправляется. Если счетчик
ссылок становится равным нулю, данный элемент более не доступен
программе и может быть перераспределен. Следовательно, система
может беспрепятственно вернуть данный элемент в свободный
список.
С этим методом связано несколько проблем. Во-первых, элементы,
организованные в циклический список, никогда не попадают в сво-
бодный список. Даже если ни один список, используемый програм-
мой, не ссылается на данный циклический список, все равно ненуле-
вые счетчики ссылок в элементах циклического списка не дают воз-
можности освободить элементы. Это препятствие трудно преодолеть,
особенно если циклические списки включены в более сложные струк-
туры. Во-вторых, во всех элементах на дополнительные поля для
счетчиков ссылок тратится значительная часть доступной памяти. По-
следнюю проблему можно частично решить, помещая счетчик только
в головной элемент каждого списка; это в какой-то степени умень-
шает объем необходимой памяти. Однако, если большинство списков
короткие, лишний расход памяти будет все же ощутимым. Третья
проблема связана с прекращением выполнения программ в результа-
те ошибок. Может оказаться, что программа более не в состоянии
получить доступ к какому-то элементу, но счетчик ссылок не умень-
шается. Поэтому данный список никогда не будет освобожден. Иног-
да, правда, эта особенность полезна. Если прерванная программа
запускается вновь, ей часто может быть удобно при восстановлении
структур данных использовать счетчики ссылок.
Второй вариант называется сборкой мусора. При этом методе
программа пользователя работает до тех пор, пока не исчерпывается
свободная память; когда же наступает этот момент, вызывается про-
грамма «сборки мусора», которая собирает все ненужные элементы.
Алгоритм сборки мусора использует в каждом элементе специальный
бит признака. Процедура сборки мусора начинается с того, что в
биты признаков всех элементов заносятся нули. Затем, начиная
с фиксированного набора элементов, к которым программа пользо-
вателя имеет непосредственный доступ (обычно это головы списков),
сборщик мусора устанавливает «1» в биты признаков всех элементов,
к которым можно получить доступ из данных базовых элементов,
следуя указателям. Все элементы с нулевыми битами признаков
считаются теперь недоступными для пользователя и могут быть
объединены в свободный список. В связи с этим методом возникают
две важные проблемы. Во-первых, если память почти заполнена,
самой программе сборки мусора остается мало рабочего места и,
следовательно, она медленно работает. Кроме того, если большинство
элементов еще нужны программе, потребуется установить очень мно-
го ненулевых битов. Во-вторых, если сборщик мусора вызывается
в середине операции со списком, он может нечаянно принять часть
настоящего списка за «мусор», если эта часть пока еще не привязана
к программе пользователя. Фрагменты активных списков часто не-
легко отличить от действительного «мусора».
При использовании сборки мусора или счетчиков ссылок память
представляется как бы поделенной на небольшие блоки свободной
памяти, рассеянные между элементами активных списков. После
установки битов признаков (или счетчиков) можно применить метод
уплотнения, в результате чего все элементы списков, активных в дан-
ный момент, переместятся в подряд стоящие ячейки в начале памяти.
Эта процедура устраняет необходимость в свободном списке, так как
все свободные элементы оказываются в последовательных ячейках
в конце памяти. В тех случаях, когда большинство элементов не-
активны, применение этого метода может сэкономить значительное
количество времени и памяти, так как не нужно образовывать сво-
бодный список. Как и для любых других методик, здесь можно по-
строить такие специальные примеры, где уплотнение будет чрезвы-
чайно неэффективно.
1.5. Стеки
Список LIFO1), называемый обычно стеком,— это список, в ко-
тором все включения и удаления производятся на одном его конце.
Операции добавления и удаления элементов стека называются соот-
ветственно ЗАТОЛКНУТЬ и ВЫТОЛКНУТЬ. При схеме последо-
вательного размещения стек можно реализовать с помощью базового
адреса и указателя на вершину стека. Операции ЗАТОЛКНУТЬ
и ВЫТОЛКНУТЬ могут быть реализованы также в одностороннем
связном списке с головным элементом. Чтобы ЗАТОЛКНУТЬ эле-
мент х в стек, УКАЗАТЕЛЮ элемента х присваивается значение
адреса верхнего элемента стека (который хранится в головном эле-
менте стека). Затем головному элементу стека присваивается адрес
элемента х. Чтобы ВЫТОЛКНУТЬ элемент из стека, содержимое
головного элемента стека присваивается некоторой свободной пере-
менной, а головной элемент подправляется таким образом, что его
ссылка будет указывать на предыдущую вершину стека.
Наиболее широко стеки используются, по-видимому, в алгоритмах
языкового грамматического разбора и в алгоритмах анализа графов.
Стеки встречаются чаще в компиляторах, чем в операционных си-
стемах, но они включены сюда для полноты изложения.
1.6. Очереди
Список FIFO2), или очередь,— это список, в котором все включе-
ния делаются на одном конце списка, а все удаления — на другом
конце. Операции над очередями ВКЛЮЧИТЬ и УДАЛИТЬ, соот-
ветствующие операциям ЗАТОЛКНУТЬ и ВЫТОЛКНУТЬ для
стеков, требуют двух указателей: одного со ссылкой на вершину
списка (для включений) и другого со ссылкой на основание списка
(для удалений). В очередях (так же, как и в стеках) исчерпание
списка (т. е. удаление из пустого списка) и переполнение (т. е. вклю-
чение элемента в уже полный список) должны рассматриваться как
ошибочные ситуации.
Очереди FIFO находят многочисленные применения в операци-
онных системах. Когда нет какой-либо дополнительной информации,
пользователи, ожидающие некоторого ресурса, обслуживаются, как
правило, по принципу FIFO.
х) Сокращение от английской фразы last-in-first-out, что означает «последним
пришел —первым ушел».— Прим, перев.
2) Сокращение от английской фразы first-in-first-out, что означает «первым
пришел — первым ушел».— Прим, перец.
1.7. Реверсивные очереди
В реверсивной очереди х) (очереди с двумя концами) включения
и удаления могут выполняться на любом конце списка. Как и в слу-
чае очередей FIFO, для реверсивной очереди нужны два указателя,
по одному на каждый конец списка. Последовательное размещение
здесь не выдвигает новых серьезных проблем сверх тех, которые
встречались в стеках и очередях, за исключением того, что приходит-
ся хранить и нижнюю, и верхнюю границу для памяти, поскольку
список растет в двух направлениях. Однако в случае связных спис-
ков все значительно усложняется. В отличие от стеков и очередей для
реверсивной очереди односторонний связный список не годится, так
как удаление элементов с обоих концов невозможно без поиска пре-
дыдущего элемента. Решить проблему можно только превратив
список в двусторонний, что, естественно, приведет и к большей слож-
ности, и к большим затратам времени в алгоритмах включения и
удаления. Реверсивная очередь может храниться также в виде цик-
лического списка с двумя внутренними указателями в обе стороны.
1.8. Таблицы
Таблица —это структура данных, в которой удаления и включе-
ния могут производиться в любом месте. Для реализации таблиц
обычно используется несколько методов. В методе хеширования
адрес хранения элемента вычисляется по содержимому или по имени
данного элемента в таблице. Например, если элементы имеют раз-
личные идентификаторы, то внутреннее (т. е. битовое) представление
каждого идентификатора можно подвергнуть какому-либо простому
арифметическому преобразованию, в результате которого получится
адрес в пределах таблицы. В идеальном случае функция хеширова-
ния должна порождать разные адреса для разных элементов. Если
же имеем неидеальный случай, то те элементы, для которых при хе-
шировании вычисляется один и тот же адрес, связываются между
собой в список. Рассмотрим, например, функцию хеширования,
которая отображает имена Л и Г в один адрес Д. Только один из
элементов может храниться по адресу Д, скажем элемент А. Эле-
мент Т хранится по некоторому адресу Д', и элемент по адресу Д
ссылается на адрес Д'. Если какой-либо третий элемент при хеширо-
вании получает адрес Д, то его поместят по новому адресу Д",
а элемент, находящийся по адресу Д', будет ссылаться на адрес Д".
Когда программа обращается к таблице, используя функцию хеши-
рования, она должна проверять, действительно ли нужный ей эле-
мент находится там, куда указывает результат хеширования по име-
х) В оригинале dequeue.— Прим, персе.
ни данного элемента. Если его нет в указанном месте, программа
должна пройти по связному списку, начиная с данного места, до тех
пор, пока она не найдет требуемый элемент.
Другой способ получения адреса в таблице связан с хранением
имен в справочнике, где содержатся также адреса элементов. Чтобы
получить доступ к некоторому элементу, выполняют поиск по спра-
вочнику, определяя местонахождение данного элемента. Здесь пред-
полагается, что поиск по упорядоченному справочнику занимает
меньше времени, чем по самой таблице. Если поиск по справочнику
реализуется аппаратным путем (обычно это параллельный поиск),
тогда мы имеем ассоциативную память; аппаратура связывает (ас-
социирует) имена элементов с адресами памяти в специальных аппа-
ратных регистрах, выборка из которых производится очень быстро.
Методы хеширования и справочники одинаково служат тому, чтобы
заданный элемент можно было найти без прямого просмотра всей
таблицы.
Приложение II
ВЫЧИСЛИТЕЛЬНЫЕ СТРУКТУРЫ
П.1. Введение
Для систем, в которых несколько процессов могут выполняться
совместно, возникает ряд проблем, не существующих для последо-
вательных систем х). Большая доля теоретических работ в области
операционных систем связана с разработкой моделей (иногда име-
нуемых схемами программ) для анализа свойств совместных систем.
Действительно, в литературе отражено более 25 различных подоб-
ных моделей [Бернстайн, 1973]. В данном приложении в качестве
характерных примеров описаны три из этих моделей: сети Петри,
вычислительные схемы и графы повторно используемых ресурсов.
II.2. Сети Петри
Сети Петри были введены как средство описания одновременного
исполнения операций в универсальных системах [Холт и Коммонер,
1970]. Они могут быть использованы для ответа на ряд интересных
вопросов, связанных с тупиковыми ситуациями в вычислительной
системе. Кроме того, можно обнаружить, что сети Петри в той или
иной форме присутствуют во многих различных моделях, описываю-
щих параллельные вычисления. Таким образом, они являются хоро-
шей отправной точкой для обсуждения программных схем.
Сеть Петри — это, по определению, помеченный ориентирован-
ный граф с двумя типами вершин, именуемых позициями и перехо-
дами, так что каждая дуга соединяет позицию с переходом или пере-
ход с позицией. Позиции обозначаются кружками, переходы —
горизонтальной чертой, а дуги — стрелками. Разметка М сети
Петри — это функция, ставящая в соответствие меткам позиций
неотрицательные целые числа. Разметка выражается в приписывании
каждой позиции некоторого числа пометок в соответствии с функ-
цией разметки. Пусть N — это сеть Петри, Р — множество позиций
в N, а п(Р) — число позиций в Р. Каждая позиция в N однозначно
связана с номером из набора номеров {1, 2, 3, ..., п(Р)}. Теперь раз-
метку М можно представить как вектор, состоящий из п(Р) элемен-
х) Термин «последовательная (совместная) система» означает: «система с по-
следовательно (совместно) выполняющимися процессами».— Прим, перев.
Рис. 11,1, Сеть Петри, которая может зависнуть. (Для этой сети Петри разметка
М = [2, 0, 0]; Р = {1, 2, 3}; п(Р) — 3; a,b,c nd — переходы.)
тов, в котором f-й элемент означает число пометок в i-й позиции.
Эти понятия иллюстрируются рис. II. 1.
Разметка сети может быть изменена с помощью запуска перехода.
Переход t называется запускаемым, если для каждой позиции х, из
которой стрелка указывает на t, существует по крайней мере одна
пометка. Запуск перехода t (при условии, что t является запуска-
емым) осуществляет следующее преобразование: для каждой дуги,
указывающей из некоторой позиции х на переход t, число пометок
в позиции х уменьшается на единицу; для каждой дуги, указываю-
щей из перехода t на некоторую позицию у, число пометок в позиции
у увеличивается на единицу. Обратившись снова к рис. II. 1, мы
видим, что переходы а и b являются запускаемыми, в то время как
переходы end незапускаемые. В результате запуска перехода а полу-
чается разметка [ 1, 1, 0]. Теперь уже запускаемыми являются
переходы а, b и с. Запустив с, мы получим новую разметку
М"=12, 0, 0].
В сетях Петри единственное ограничение на совместное выполне-
ние переходов налагается числом пометок в позиции. Таким обра-
зом, при исходной разметке на рис. II. 1 переходы а и b могли бы
быть запущены одновременно. То, что два перехода являются за-
пускаемыми в один и тот же момент, не означает обязательно, что
они могут быть запущены совместно. Если бы разметка на рис. II. 1
была М = [ 1, 0, 0], то оба перехода а и b были бы запускаемыми, но
не могли бы быть запущены одновременно. Это происходит потому,
что как для а, так и для b для выполнения запуска требуется убрать
пометку в позиции 1 (т. е. вместе две пометки).
Семантически позиции представляют собой условия, а переходы —
события в системе. Входные позиции перехода t (т. е. позиции с ду-
гами, указывающими на переход t) соответствуют условиям, влияю-
щим на осуществление события t. Выходные позиции t соответствуют
воздействию на систему осуществления этого события. Присутствие
пометки в некоторой позиции означает, что условие, представленное
этой позицией, выполнено. Операция запуска означает, что, если
все условия, от которых зависит событие, выполнены, то событие
осуществляется и выполняются его выходные условия.
Рассмотрим сеть Петри N с начальной разметкой Л4(0). После-
довательность исполнения N — это последовательность разметок
Л4(0), Л4(1), 7И(2), ..., где Л4(/+1) получается из М (i) в результате
запуска некоторого перехода. Вообще говоря, для данной сети Петри
с начальной разметкой существует много возможных последователь-
ностей исполнения. Живучая разметка — это такая, при которой
каждый из переходов сможет запускаться бесконечное число раз х).
Когда достигнута такая разметка, при которой ни один из переходов
не может быть запущен, говорят, что сеть Петри зависла (т. е. имеет
место тупиковая ситуация). Если система моделируется сетью Петри
с некоторой начальной разметкой, которая является живучей, то
система в целом никогда не остановится, так как невозможно достичь
разметки, при которой не сможет произойти ни одного события.
На рис. II.1 представлена начальная разметка М(0) = [2, 0, 0].
Если запускаются и а, и ft, то достигается разметка М(2) = [0, 1, 1].
Теперь сеть Петри мертва. Ни один переход не может быть запущен.
Следовательно, разметка Л1(0) не является живучей. На самом деле
для этой сети Петри не существует живучих разметок. Независимо
от того, сколько пометок помещено в позицию 1, всегда можно за-
пускать переходы а и b до тех пор, пока все пометки не разместятся
в позициях 2 и 3. Как только позиция 1 становится пустой, эта сеть
Петри «умирает».
Говорят, что два перехода конфликтуют, если они взаимно ис-
ключают друг друга (т. е. если они не могут быть оба запущены одно-
временно). Хотя точные условия, при которых происходит конфликт,
формально не определены, ясно, что суть конфликта тесно связана
с типом тупиковой ситуации, с которым мы столкнулись на рис. II. 1
(где переходы с и d конфликтуют при разметке Л4(0)).
Размеченный граф — это сеть Петри, в которой с каждой пози-
цией связано в точности по одной входящей и выходящей дуге.
Размеченные графы несколько менее общи, чем сети Петри, и,
следовательно, легче анализируются. Для размеченных графов
доказан ряд теорем, связанных со свойствами зависания и свой-
ствами конечности. В частности, было показано, что для сильно
связанных размеченных графов мертвый переход (т. е. переход,
который никогда не может быть запущен) существует в том и толь-
ко том случае, если существует ориентированный цикл без поме-
х) Подразумевается, что бесконечное число запусков сможет произойти неза-
висимо от выбора конкретной последовательности исполнения.— Прим. ред.
ток. Если переходы соответ-
ствуют некоторым процессам,
то эта теорема может приме-
няться к системам, моделиру-
емым размеченными графами.
Для общих сетей Петри не
удалось отыскать никакого
аналогичного утверждения.
В размеченном графе на
рис. II.2 переход а мертв,
так как дуги 1 и 2 образуют
ориентированный цикл, не
содержащий пометок.
Говорят, что разметка М
сети Петри N надежна, если
ни для какой разметки, по-
лученной из М с помощью
запуска переходов, ни одна
из позиций не может иметь
более одной пометки. Для
размеченных графов сущест-
вует ряд результатов, кото-
рые связывают живучесть с
надежностью.
Сеть Петри называется ди-
аграммой переходов, если каж-
дый переход имеет не более
одного входа и одного выхода.
Хотя как для* размеченных
графов, так и 'для диаграмм
переходов получено много
хороших теорем, тем не менее
для описания взаимосвязей в
операционных системах обыч-
но требуется полная описа-
тельная мощь общих сетей
Петри.
Для примера рассмотрим
простую взаимно исключаю-
щую СВЯЗЬ между двумя про- рис //.3. Взаимное исключение с исполь-
цессами А И В (рис. II. 3). зованием сети Петри.
Переход А 1(В1) запускается
тогда, когда процессу Д(В) необходимо войти в свой критиче-
ский участок. Переход А2(В2) запускается, когда процесс А(В) поки-
дает свой критический участок. Для того чтобы Д1 и В1 были вза-
имно исключающими, необходимо, чтобы у них была общая входная
позиция (т. е. «взаискл»). Следовательно, так как «взаискл» имеет
два выхода, эта сеть Петри уже не является размеченным графом.
К тому же А1 и В1 запускаются, только если они готовы (т. е.
если РА или РВ содержит пометку) и «взаискл» позволяет (т. е.
также содержит пометку); поэтому и для Л1 и для В\ необходимо
по два входа. Следовательно, эта сеть Петри не является и диаграм-
мой переходов. То, что эта модель простой взаимосвязи между двумя
процессами представляет собой общую сеть Петри, не особенно об-
надеживает, так как теоремы, доказанные для менее общих моделей,
здесь не применимы.
П.З. Вычислительные схемы
Хотя сетей Петри вполне достаточно для описания взаимодей-
ствия событий в системе, они не обеспечивают полной общности
с вычислительной точки зрения. Например, оператор «не» (т. е.
запуск перехода в том и только том случае, когда позиция свободна)
нельзя смоделировать с помощью сетей Петри. В данном разделе
приведен пример полной схемы для описания вычислений. Вычи-
слительная схема — это представление в графической форме асин-
хронной системы, состоящей из набора операторов (т. е. процес-
сов), которые воздействуют на множество регистров (т. е. ячеек
памяти). Каждая схема полностью определяется двумя графами:
графом потока данных и графом управления.
П.3.1. Определения
Граф потока данных определяет регистры входных данных и
выходных данных каждого оператора. Дуга от оператора z к ре-
гистру г означает, что г является регистром выходных данных г.
Дуга от г к г означает, что г является регистром входных данных z.
На рис. II. 4 показан граф потока данных некоторой вычислитель-
ной схемы. Операторы и регистры представлены кружками и квад-
ратами соответственно.
Граф управления определяет последовательность выполнения
операторов. Каждый оператор (представленный кружком) связан с
некоторым количеством управляющих счетчиков (представленных
квадратами), каждый из которых содержит неотрицательное целое
число. Числа, записанные внутри квадратов, являются началь-
ными значениями счетчиков. Пример графа управления для не-
которой вычислительной схемы приведен на рис. II.5.
Если все счетчики, указывающие на оператор (т. е. входные
счетчики), имеют ненулевые значения, то говорят, что оператор опре-
делен. Если оператор определен, то он может выполниться в любой
момент, изменив регистры в соответствии с графом потока данных
Оператор Вход Выход
a to} W
6 Ы Ы
с {А, W
Рис. 11.4. Граф потока данных.
и следующим образом преобразовав счетчики графа управления:
значения всех входных счетчиков оператора уменьшаются на еди-
ницу; значение каждого из выходных счетчиков увеличивается на
некоторое неотрицательное целое число. Если для данного выход-
ного счетчика это приращение постоянно, то оно записывается ря-
дом с соответствующей дугой, как для операторов а и с на рис. II.5.
Для того чтобы ввести возможность влияния данных на последова-
тельность выполнения операторов, допускается, что изменение вы-
ходного счетчика может задаваться с помощью функции от значе-
ний регистров, на которые указывает оператор, как для оператора
b на рис. II.5.
Обратите внимание на сходство между графом управления и сетью
Петри. Если под операторами и счетчиками понимать переходы и
позиции, то единственным существенным различием между двумя
представлениями будет приращение счетчика, зависящее от данных.
Обычно операторы в графе потока данных представляются как
произвольные функции, а управляющие решения (основанные на
Рис. //.5. Граф управления.
значениях счетчиков) в графе управления — как произвольные
предикаты. В этом случае говорят, что схема не интерпретирована.
Интерпретация схемы заключается в замене символов функций и
предикатов на фактические функции и предикаты. Интерпретация,
как правило, включает задание области значений регистров. Схема,
определенная на рис. II.4 и II.5, не интерпретирована. Интерпре-
тация этой схемы должна была бы включать:
I) область значений регистров rl, г2 и гЗ;
2) описание функций для операторов а, b и с\
3) целочисленную функцию для р ( ) в графе управления.
Последовательностью исполнения схемы называется (возможно,
бесконечная) последовательность имен операторов XI, Х2, . . .
. . . , Хп, . . . , такая, что каждый оператор Xi определен (т. е.
все его входные счетчики ^>1) при тех значениях счетчиков, которые
получаются в результате выполнения предшествующих операторов
последовательности. Последовательность исполнения XI, . . .,
Хп называется завершенной, если ни один оператор не определен
после выполнения XI, . . ., Хп. Каждая последовательность испол-
нения определяет массив истории, который для каждого регистра
содержит последовательность значений, принимаемых этим ре-
гистром. Таблица II. 1 связывает понятия последовательности
исполнения и массива истории.
Таблица 11.1
Массив истории для вычислительной схемы х)
Регистр . Значения
*1 Л (Xi)
Г2 Х2 bixj)
Г 3 Х3 с (a (Xi), b(x2))
9 Рассматривается схема, представленная графами на рис. II.4 и II.5. Единствен-
ными завершенными последовательностями исполнения яйЛЯются пбслёдбватёЛьнйсги
а, Ь, с и Ь, а, с. Данный массив истории соответствует обеим последовательностям.
П.3.2. Детерминированность, функциональность
и тупиковая ситуация
Ввиду того что с операторами не связано никакого особого от-
счета времени, порядок, в котором операторы будут начинать и
завершать свою работу, не всегда может быть предсказан. Любая
допустимая последовательность исполнения является возможной
последовательностью событий. Вообще, можно было бы пожелать,
Рис. 11.6. Недетерминированная вычислительная схема.
чтобы схема при каждом исполнении «делала бы одно и то же».
Однако вполне возможно, что результаты вычислений зависят от
последовательности исполнения. В том случае, когда схема вы-
рабатывает одинаковые результаты для всех допустимых последо-
вательностей исполнения при любой интерпретации, говорят, что
она детерминирована.
Рассмотрим вычислительную схему на рис. II.6. Предположим,
что оператор а заносит нуль в регистр rl. Оператор Ь читает rl и
заносит его в г2. Очевидно, что значение г2 будет различным в за-
висимости оттого, выполняется ли оператор b раньше или позже а.
Однако граф управления допускает обе последовательности испол-
нения (т. е. а, b и Ь, а). Следовательно, эта схема не детерминиро-
вана.
Говорят, что два оператора соперничают в регистре г, если один
из них изменяет г, а другой либо изменяет, либо обращается к г.
Если два оператора, которые соперничают в некотором регистре,
могут быть определены в одно и то же время, то говорят, что в схеме
существует условие соперничества, и такая схема является недетер-
минированной. На рис. II.6 операторы а и b соперничают в регистре
rl. Имеет место условие соперничества, так как оба оператора перво-
начально опеределены.
Схема называется полностью функциональной, если для любой
последовательности исполнения каждый регистр пробегает одну и
ту же последовательность значений, т. е. все массивы истории для
этой схемы одинаковы. Если имеет место условие соперничества,
то схема не будет полностью функциональной для всех интерпре-
таций.
Вместо требования, чтобы схема была полностью функциональ-
ной, можно определить некоторое подмножество регистров как
выходные регистры. В том случае, когда все массивы истории для
выходных регистров одинаковы для всех последовательностей испол-
нения, говорят, что скепафункциональна на выходе. Если на рис. II. 7
регистры гЗ и г5 — единственные выходные регистры, то схема
функциональна на выходе. Она не полностью функциональна, так
Рис. II.7. Пример функциональности на выходе, (а) Граф потока данных; (Ь) граф
управления. (Если регистры гЗ и г5— единственные выходные регистры, то схема
функциональна на выходе. Она не является полностью функциональной, так как
для г2 существуют две возможные истории (а именно: [a (rl), с(г4)] или [с(г4),
а (г1)1.)
как для регистра г2 существуют две возможные истории (т. е.
[a (rl), с (г4)] или [с (r4), a (rl)]).
Другая возможная форма недетерминированного исполнения
заключается в том, что схема может преждевременно «зависнуть»,
если произойдет определенная последовательность событий (на-
пример, рис. II.8). Это понятие аналогично «живучести» в сетях
Петри. Заметьте сходство между рис. II.8 и рис. II. 1. Это по су-
ществу одна и та же система, моделируемая двумя различными аб-
страктными схемами: сетями Петри и вычислительными схемами.
П.З.З. Схемы программ. Заключение
Сети Петри и вычислительные схемы представляют собой лишь
два примера большого класса моделей для параллельных систем.
К сожалению, эти модели принесли не много непосредственной поль-
зы разработчикам операционных систем, несмотря на свою интуи-
тивную привлекательность. Однако все же существуют невычисли-
тельные модели, которые отвлекаются от фактических вычислитель-
ных функций и уделяют основное внимание специальным пробле-
мам, связанным с совместным использованием ресурсов. В следую-
щем разделе исследуется одна такая модель.
Рис. 11.8. Пример схемы, которая зависает, (а) Граф потока данных; (Ь) граф
управления. (Счетчик, помеченный буквой /?, представляет собой ресурс, не-
обходимый каждому оператору, но не освобождаемый, пока не завершится b
или d. Последовательности исполнения a, b, с, d и с, d, а, b вычисляют тре-
буемые результаты в гЗ и гб, но если а выполняется первым, а за ним вы-
полняется с, то ни by ни d не могут выполняться, и исполнение заканчивается
неправильно.)
IL4. Модель для проблемы тупика
Как в сетях Петри, так и в вычислительных схемах мы неожи-
данно сталкивались с проблемой тупиковых ситуаций. Для иссле-
дования тупиков было разработано несколько невычислительных
моделей (например, Коффман и др. [1971], Хаберман [1969], Хе-
балкар [1970], Холт [1972]). В качестве примера таких моделей рас-
сматривается модель повторно используемых ресурсов Р. Холта
[Холт, 1972].
В модели повторно используемых ресурсов система представля-
ется как набор процессов и набор ресурсов, причем каждый из ре-
сурсов состоит из фиксированного числа единиц. Процесс может
изменять состояние системы с помощью запроса, получения или
освобождения единицы ресурса. В графической форме процессы и
ресурсы представлены квадратами и кружками соответственно.
Каждый кружок содержит некоторое число пометок в соответствии
Рис. 11.9. Пример графа повторно используемых ресурсов, (а) Начальное состоя-
ние; (Ь) состояние после предоставления Р1 одной единицы R2.
с существующим числом единиц этого ресурса. Дуга, указывающая
из процесса на ресурс, означает запрос одной единицы этого ресурса.
Дуга, указывающая из ресурса на процесс, представляет выделение
ресурса процессу. Так как каждая единица любого ресурса может
быть выделена одновременно не более чем одному процессу, число
дуг, исходящих из ресурса к различным процессам, не может
превышать общего числа единиц этого ресурса.
На рис. 11.9(a) представлено одно из состояний системы пов-
торно используемых ресурсов. Процесс Р1 запрашивает две единицы
ресурса Ri и одну единицу ресурса R2. Процессу Р2 принадлежат
две единицы 7?1, и ему нужна одна единица R2. Предположим, что
процесс Pi получил бы теперь запрошенную им единицу R2. Если
принято правило, по которому процесс должен получить все запро-
шенные им ресурсы, прежде чем освободить хотя бы один из них,
то удовлетворение запроса Pi приводит к тупиковой ситуации.
Р1 не может продолжаться до тех пор, пока Р2 не освободит еди-
ницу Ri, а Р2 не может продолжаться до тех пор, пока PI не осво-
бодит единицу R2.
Приведение Р2
Приведение Р1
Рис. 11.10. Приведение графа повторно используемых ресурсов,
Рис. 11.11. Тупик в графе повторно используемых ресурсов. (Р1 и Р2 находятся
в тупиковом состоянии, так как они содержатся в пучке.)
Используя эти формальные обозначения, можно выявить тупи-
ковую ситуацию с помощью приведения графа в соответствии со
следующим правилом: для каждого незаблокированного процесса,
т. е. такого процесса, все запросы которого могут быть удовлетво-
рены, нужно убрать все входящие и исходящие дуги. Граф назы-
вается полностью приводимым, если после приведения он не со-
держит ни одной дуги. Существует теорема, что в системе, представ-
ленной такой моделью, отсутствуют тупиковые ситуации, если соот-
ветствующий граф полностью приводим. На рис. 11.10 система,
введенная на рис. 11.9(a), приведена. Граф на рис. И.9 (Ь) не может
быть приведен, так как оба процесса заблокированы.
В графе потомством вершины а называется множество всех вер-
шин, в которые ведут пути из а. Пучок — это множество К вершин,
в котором потомством каждой вершины из К является само Л. На
рис. 11.11 вершины {7?1, /?2, Pl, Р2] образуют пучок. Состояние
называется рациональным, если каждый процесс, выдавший запрос,
заблокирован. Таким образом, система на рис. 11.11 рациональна.
Холт доказывает, что в рациональной системе достаточным усло-
вием для тупика является наличие пучка.
Ресурсы, такие, как сообщения, число которых может меняться
в процессе работы системы, называются расходуемыми. Используя
как расходуемые, так и повторно используемые ресурсы, можно
построить разумное представление вычислительной системы с по-
мощью этой модели. Был предложен ряд алгоритмов, которые при-
меняли эту модель для обнаружения и предотвращения тупиков в
процессе работы [Холт, 1972].
Графы повторно используемых ресурсов моделируют состояния
системы в терминах запросов и распределения ресурсов между про-
цессами. Однако моделировать состояния системы можно и по-дру-
гому. Например, Холт устанавливает связь между своей моделью
и сетями Петри, показывая, как состояния сети Петри могут мо-
делировать состояния графа ресурсов.
Предшествующее обсуждение модели Холта несколько упрощено.
Фактически эта модель является весьма содержательной и описы-
вает множество интересных случаев взаимодействия процессов.
Рассмотрение этого вопроса здесь было по необходимости кратким
из-за отсутствия места. Подробно эта модель рассматривается Хол-
том [1972].
II.5. Заключение
Всюду в этой книге авторы сознательно старались избегать чрез-
мерного формализма. Математические модели и/или результаты важ-
ны только тогда, когда они дают дополнительное понимание или
намек на решение серьезной проблемы. К сожалению, большинство
теоретических результатов, полученных под воздействием проблем,
стоящих в операционных системах, не может быть непосредственно
применено. Это не означает, что их следует отвергнуть. Хорошая
теория сама по себе полезна. Она помогает студентам увидеть и
постигнуть понятия. Иногда она даже предлагает некоторые новые
идеи.
В этом приложении были представлены некоторые теоретические
модели, которые до некоторой степени проясняют проблемы, воз-
никающие в связи с параллельным выполнением операций. Тем са-
мым они могут помочь разработчику лучше понять структуру и
взаимосвязи процессов в операционной системе.
Приложение III
«ИГРУШЕЧНАЯ»
ОПЕРАЦИОННАЯ СИСТЕМА
III. 1. Введение
В курсе по операционным системам студенты изучают принципы
и основные методы. Примеры и упражнения помогают им понять,
как можно практически применять эти методы. К сожалению, од-
них лекций не достаточно. Для того чтобы студент правильно оценил
некоторые проблемы, он должен встретиться с ними лицом к лицу.
Если он почувствует важность какой-либо проблемы, он будет
добросовестно усваивать соответствующий материал. Истинное
знание возможно в том случае, когда оно кому-либо нужно. Создание
силами студентов «игрушечной» операционной системы имело целью
поставить студентов перед проблемами проектирования программно-
го обеспечения.
При разработке данной системы студенты были организованы
в бригады по два или три человека. Координация их действий в ра-
боте над проектом программного обеспечения была сама по себе не-
легкой задачей. На семинаре по вычислительным машинам послед-
него курса студенты пишут много программ, но это обычно «игру-
шечные» программы, которые можно написать без всякой органи-
зующей дисциплины. «Игрушечная» операционная система тем не
менее не является «игрушечной» программой. Это сложная програм-
ма, которую нужно спроектировать, реализовать и отладить орга-
низованным образом. Студенту не стоит рассчитывать на то, что,
сидя перед листом бумаги, он сможет в мгновение ока постичь все
идеи. Он не сможет также спроектировать операционную систему,
даже «игрушечную», не владея по-настоящему многим из того ма-
териала, который описан в различных главах этой книги.
Основная трудность в деле привития студентам практических
навыков по разработке операционных систем связана со стоимостью
обучения. Им нельзя разрешить вносить изменения в производствен-
ную операционную систему университета. Это было бы слишком до-
рого в отношении затрат и могло бы ухудшить обслуживание других
пользователей. Следовательно, должны быть созданы такие усло-
вия, которые моделировали бы многие из задач операционной сис-
темы. Главное требование при создании таких условий — это на-
личие языка, в котором допускаются сопрограммы или параллельное
выполнение процессов, как, например, в языке PL/I с мультиза-
дачными возможностями. В университете Торонто «игрушечная»
система была запрограммирована на языке TOPPS, который обе-
спечивает параллельные процессы и основные операции синхрони-
зации [Холт, Кинред, 1972]. Язык TOPPS не использует мульти-
задачные возможности системы (имеется в виду система IBM OS/360),
однако с помощью интерпретации он моделирует многопроцессор-
ную работу. Это сказалось на значительном уменьшении стоимости
программ и устранило возможность создания студентами тупиков
в реальной системе.
Задача состояла в том, чтобы написать мультипрограммную
систему с буферизацией ввода-вывода на языке параллельного
программирования. Всю систему можно рассматривать как сово-
купность взаимодействующих аппаратных устройств и программных
процессов. Аппаратные устройства моделировались программами,
которые представлялись студентам в готовом виде как часть проек-
тных спецификаций. Поскольку операционная система написана на
том же языке, который использовался для моделирования аппара-
туры, проблемы интерфейса между аппаратной и программной час-
тями системы были решены легко. Устранение трудностей в орга-
низации интерфейса с аппаратурой явилось одним из ключевых
условий снижения трудоемкости задания. На реальной машине
ввиду сложности аппаратуры было бы, безусловно, невозможно
выполнить данный проект в течение одного семестра.
Задание, предлагаемое студентам в университете Торонто, ос-
новано на проекте «игрушечной» операционной системы, разрабо-
танном Р. Холтом. В литературе описаны подобные проекты [Шоу и
Вайдерман, 1971].
В следующем разделе представлены предложения по проекти-
рованию моделируемой машины. Многие из этих предложений опи-
раются на наш опыт [Зарникидр., 1973]. В разд. III. 3 обсуждаются
основные аспекты написания малой операционной системы для дан-
ной моделируемой машины.
III.2. Моделируемая аппаратура
Главное свойство машины с моделируемой аппаратурой состоит
в том, что она обеспечивает очень четкий интерфейс для «игрушеч-
ной» операционной системы. Это наилучшим образом помогает из-
бежать сложной структуры системных или программных прерыва-
ний и обойтись без изощрений машинного языка. Команды запуска
любого аппаратного устройства также должны быть простыми.
Даже для простой, хорошо сконструированной машины написать
систему достаточно трудно. И хотя на практике сложность аппара-
туры служит источником интересных проблем реализации, она же
приводит к тому, что проект становится слишком большим для кур-
са, рассчитанного на один семестр.
Аппаратная система состоит из устройства считывания перфо-
карт, устройства печати, центрального процессора, оперативной
памяти и устройства внешней памяти, например барабана. Сердце
системы — это центральный процессор, который выполняет програм-
мы пользователей, хранящиеся в оперативной памяти. И хотя лю-
бой простой и удобный для интерпретации машинный язык может
служить в качестве языка для пользователей, все же можно попы-
таться использовать более совершенный язык ассемблера или язык
высокого уровня. В оперативной памяти, представленной в языке
параллельного программирования массивом, хранятся программы
пользователей и данные. Центральный процессор начинает работу,
когда ему передается «слово состояния процесса», которое состоит
из значений всех внутренних регистров процесса, таких, как счет-
чик команд, общие регистры, регистр таблицы страниц или регистр
с началом и длиной сегмента. Затем центральный процессор вы-
полняет команды до появления программных прерываний. Преры-
вание может быть вызвано запросом на ввод-вывод или в результате
попытки выполнить незаконное действие. В этот момент должна
быть вызвана операционная система, которая предпримет необхо-
димые действия. Способ вызова операционной системы зависит от
структур управления, имеющихся в данном языке с параллельными
процессами.
Устройство считывания перфокарт и устройство печати могут
быть запущены при передаче им адреса оперативной памяти и,
возможно, поля длины. Для барабана требуется два адреса и код
операции, определяющей, в каком направлении должны переда-
ваться данные. И в этом случае способ, которым указанные устройст-
ва сообщают «игрушечной» операционной системе о завершении вво-
да-вывода, зависит от используемого языка.
Операционная система для этой машины написана на языке,
имеющем средства параллельного выполнения процессов, а не на
языке пользователей. Это можно объяснить хотя бы тем, что язык
с параллельными процессами реализует один пользовательский
процесс (т. е. процесс, моделирующий центральный процессор),
один процесс, моделирующий устройство печати, один процесс,
моделирующий устройство считывания перфокарт, один процесс,
моделирующий барабан, и произвольное число системных процес-
сов. Программы пользователей могут выполняться, только на одном
процессе, моделирующем центральный процессор. Каждой систем-
ной программе разрешается иметь свой собственный виртуальный
процессор. Системные процессы должны обеспечить выполнение
программ всех пользователей с помощью одного пользовательского
процесса.
Описанная выше машина предлагается только как набросок.
Фактически возможна любая разумная архитектура машины. Од-
нако применительно к учебному курсу сложная машина допустима
только в том случае, если готовые программы моделирования аппа-
ратуры предоставляются студентам как часть проектных спе-
цификаций. Но даже и тогда для сложных машин обычно тре-
буются сложные системы. С педагогической точки зрения, по-
видимому, все же лучше, чтобы проект был простым [Зарник
и др., 1973].
II 1.3. „Игрушечная" операционная система
Требования к «игрушечной» операционной системе заключаются
в том, что она должна организовать буферизацию ввода-вывода и
выполнять задания пользователей в мультипрограммном режиме.
Большинство существующих операционных систем имеет, по мень-
шей мере, эти основные возможности — буферизацию и мульти-
программирование. Операционная система читает задания, посту-
пающие из устройства считывания перфокарт, и помещает их на
барабан. Задания выбираются в оперативную память, когда для
них оказывается достаточно места, и там они выполняются в мульти-
программном режиме. Если одно задание приостановлено в ожи-
дании операции ввода-вывода, центральный процессор может быть
отдан другому заданию. Выводимый на печать материал буфери-
зуется в оперативной памяти, а затем переносится опять-таки на
барабан. После окончания выполнения заданий выводной материал
передается с барабана на устройство печати. Многие из этих работ,
естественно, производятся одновременно. Таким образом, считы-
вание заданий и печать результатов идут параллельно с работой
барабана и центрального процессора.
Операционная система должна выполнять много функций. Она
вводит новые задания на барабан, печатает выдачи законченных
заданий с барабана, загружает задания в оперативную память,
обслуживает прерывания в программах пользователей, планирует
очередность выполнения заданий на центральном процессоре и
разгружает оперативную память от уже выполненных заданий.
Для реализации этих независимых средств обслуживания имеется
много возможных структур. Каждое средство может быть отдельным
процессом, или несколько средств могут быть сгруппированы в один
процесс. Так, например, один способ организации состоит в том,
чтобы с каждым из трех периферийных устройств связать свой про-
цесс, который организовывал бы очереди запросов к данному
устройству. Четвертый процесс может в этом случае отвечать за
прохождение заданий пользователей и планировать использование
центрального процессора.
111.4. Заключение
Проект «игрушечной» операционной системы, описанный в пре-
дыдущих разделах, дает студентам возможность приобрести опыт
практической разработки систем. Студенты знакомятся с различ-
ными ресурсами, имеющимися в системе, и со способами их распре-
деления. Однако в осуществлении такого проекта встречаются труд-
ности организационного порядка [Зарник и др., 1973].
Первая трудность связана со стоимостью. Каждой бригаде сту-
дентов разрешается затратить на выполнение проекта около 15 ми-
нут времени на машине IBM 370/165. Читатель может проэкстра-
полировать соответствующую стоимость для своей собственной
машины. По существующим нормам это довольно дорого. Умень-
шение сложности системы может в некоторой степени уменьшить
общую стоимость. Не исключено, что целесообразно также еще
жестче ограничить количество времени, потребляемого каждой
бригадой. Во всяком случае, экспериментальные работы с операци-
онными системами не могут быть очень дешевы.
Вторая трудность в реализации проекта связана с его слож-
ностью. Для многих студентов старших курсов оказывается трудно
завершить проект за один семестр. Студентов следовало бы поощрять
к тому, чтобы они добивались простоты в системе. Другой путь
состоит в том, чтобы дать студентам как часть проектных специфи-
каций готовую очень простую однопрограммную систему, которую
им нужно расширить до требуемой проектом мультипрограммной
системы с буферизацией ввода-вывода. Этот способ имеет допол-
нительное преимущество, так как уменьшает стоимость выполнения
проекта.
Третья трудность заключается в необходимости предваритель-
ных трудовых затрат. Для начальной подготовки проектного за-
дания нужно выполнить определенную работу. На многих вычисли-
тельных установках не.реализован язык с параллельными процес-
сами, который, очевидно, является необходимым инструментом.
Кроме того, учебное задание такого рода требует подробных специ-
фикаций. Полное описание задания занимает, как правило, от 10
до 20 страниц [Зарник и др., 1973].
Четвертая проблема — организационная. Руководство таким про-
ектом отнимает довольно много времени. Студентов нужно контро-
лировать по их общей производительности, включая качество про-
ектирования и документации, число потребовавшихся запусков и
т. д. Контроль работы над проектом также требует времени. Ассис-
тенты, принимающие участие в руководстве проектом, должны уметь
хорошо читать чужие программы.
В университете Торонто студенты были очень увлечены проектом
и считали, что это полезный эксперимент. Иногда, однако, слишком
широко задуманные проекты систем налагают на студентов огром-
11*
ную нагрузку, что отрицательно влияет на их работу по другим
предметам и затрудняет руководство студентами по данному пред-
мету. И тем не менее такая базовая система, которая была описана
в разд. III.3, может быть полностью закончена за один семестр боль-
шинством студентов с приемлемыми затратами труда при условии,
что им будут заданы хорошие спецификации проекта, и в частности
такие элементы спецификации, как программы моделирования ап-
паратуры.
СПИСОК ЛИТЕРАТУРЫ
В библиографии использованы следующие сокращения:
САСМ — Communications of the Association for Computing Machinery,
J ACM — Journal of the Association for Computing Machinery,
SJCC — Spring Joint Computer Conference,
FJCC — Fall Joint Computer Conference,
AFIPS — American Federation of Information Processing Societies.
Александер (Alexander C.)
1964 Notes on the Synthesis of Form, Harvard Univ. Press, Cambridge, Massachu-
setts.
В этой книге излагается точка зрения разработчика систем на проектирование
больших систем. Особое внимание уделено поиску естественного разбиения систем
на составные части.
Атвуд (ред.), Кларк, Грушков, Холт, Хорнинг, Севсик, Цикритзис
(Atwood J. W., Clark В. L., Grushcow М. S., Holt R. С., Horning J. J.,
Sevcik К. C., Tsichritzis D.)
1972 Project SUE Status Rep., Tech. Rep. CSRG-11. Comput. System Res. Group,
Univ, of Toronto, Toronto.
Это первый основной документ, описывающий проект SUE. Со времени выхода
данного отчета система претерпела значительную эволюцию, поэтому некоторые
его положения устарели.
Ахо, Деннинг, Улман (Aho А. V., Denning Р. J., Ullman J. D.)
1971 Principles of Optimal Page Replacement, J ACM, 18, No. 1 (Jan.), 80—93
Показано, что при определенных условиях смена страниц по требованию, по край-
ней мере, не хуже, чем любое другое правило замещения страниц. Затем разви-
вается теоретическая модель, с помощью которой анализируется эффективность
определенных алгоритмов замещения страниц.
Бакстон, Ренделл (Buxton J. N., Randell В.)
1970 Software Engineering Techniques, NATO Sci. Affairs Div., Brussels.
Это отчет о конференции НАТО по созданию программного обеспечения. Отчет
включает материалы по доказательству правильности программ, мобильности
программного обеспечения и содержит подробное описание нескольких больших
систем.
Баллард, Цикритзис (Ballard A. J., Tsichritzis D.)
1973 Structure and Correctness of Systems, Proc. Canad. Comput. Conf.,
Edmonton (June), 324—340.
Обсуждаются специфические трудности проверки больших систем. Предлагается
подход к доказательству правильности систем.
Бард (Bard Y.)
1971 Performance Criteria and Measurement in a Time-Sharing System, IBM
Systems J., 19, No. 3, 193—216.
Описаны статистические методы оценки операционной системы СР-67 до и после
некоторых модификаций. С помощью этих методов измерялся общий эффект изме-
нений и оценивался вклад каждого изменения.
Бейкер (Baker F. Т.)
1972 Chief Programmer Team Management of Production Programming, IBM
Systems J., 11, No. 3, 56—71.
В связи с проектом информационного банка газеты «Нью-Йорк Таймс», обсужда-
ется метод руководства проектом, называемый методом «главного программиста».
Белл, Голд (Bell С. G., Gold М. М.)
1971 An Introduction to the Structure of Time-Shared Computers, Advances in
Information Sci., 4, 161—272.
Обсуждаются вопросы, связанные co структурой и внешними характеристиками
аппаратуры вычислительных систем разделения времени и операционных систем,
обеспечивающих разделение времени. В качестве примера дается подробное ис-
следование разделения времени на машине PDP-10.
Бернстайн А., Детлфсен, Керр (Bernstein A. J., Detlefsen G. D., Kerr R. Н.)
1969 Process Control and Communication, Proc. Second ACM Symp. Operating
Systems Principles (Oct.), 60—66.
Описан механизм связи между процессами, использующий очереди событий*
Для событий имеются операции CAUSE (ВЫЗВАТЬ) и MODIFY (МОДИФИЦИРО-
ВАТЬ) и обратные им операции UNCAUSE (НЕ ВЫЗЫВАТЬ) и DELETE (УДА-
ЛИТЬ). Эти средства являются интересной альтернативой тем средствам, которые
обсуждались в главе 2.
Бернстайн А., Шарп (Bernstein A. J., Sharp J. С.)
1971 A Policy-Driven Scheduler for a Time-Sharing System, САСМ, 14, No. 2
(Feb.), 74—78.
Описан алгоритм планирования, основанный на некоторой стратегической функ-
ции, связанной с каждым пользователем. Функция определяет, какое количество
обслуживания пользователь может получить в каждый момент времени. Приори-
тет пользователя здесь меняется в зависимости от разности между требуемым по
стратегической функции обслуживанием и реально получаемым обслуживанием.
Дается анализ предложенного алгоритма и описана некоторая его реализация’
Бернстайн П. (Bernstein Р. А.)
1973 Description Problems in the Modeling of Asynchronous Computer Systems,
Tech. Rep. No. 48, Dept, of Comput. Sci., Univ, of Toronto, Toronto.
Описано двенадцать моделей для параллельных систем и проведено сравнение
по их описательной силе. Данный отчет включает обширную библиографию по
схемам программ.
Биледи (Belady L. А.)
1966 A Study of Replacement Algorithms for a Virtual Storage Computer, IBM
Systems J., 5, No. 2, 78—101.
Алгоритмы замещения страниц классифицируются по количеству используемой
ими информации о программе. Описан оптимальный алгоритм (см. также Мэттсон
и др., (1970]) и анализируются результаты моделирования для некоторых алго-
ритмов замещения.
Биледи, Кюнер (Belady L. A., Kuehner С. J.)
1969 Dynamic Space-Sharing in Computer Systems, CACM, 12, No. 5 (May),
282—288.
Предложен алгоритм для анализа соотношения между используемым объемом па-
мяти и временем процессора. При помощи этого метода сравниваются два алгорит-
ма замещения страниц.
Биледи, Леман (Belady L. A., Lehman М. М.)
1971 Programming System Dynamics or the Meta-Dynamics of Systems in Main-
tenance and Growth, No. RC3546, IBM Res. Center, Yorktown Heights, New
York (Sept.).
Предложена модель для изучения расширения больших систем программирова-
ния. Модифицируемое с течением времени программное обеспечение, которое
поэтому становится более сложным, затрудняет эксплуатацию системы. Авторы
доказывают, что экспоненциальный рост усилий по поддержанию некоторых боль-
ших систем программного обеспечения неизбежен. Отсюда вытекает, что век га-
рантированной работы этих систем ограничен.
Биледи, Нельсон, Шедлер (Belady L. A., Nelson R. A., Shedler G. S.)
1969 An Anomaly in Space-Time Characteristics of Certain Programs Running
in a Paging Environment, CACM, 12, No. 6 (June), 349—353.
Показано, что при замещении страниц по принципу FIFO увеличение объема
памяти для размещения страниц может в случае аномальных типов ссылок при-
вести к росту числа подкачек, связанных с обращением к страницам. Мэттсоном
и др. [1970] было показано, что стековые алгоритмы (в отличие от алгоритмов
FIFO) не имеют данного эффекта (см. также 5.4.2.2).
Бринч Хансен (Brinch Hansen Р.)
1970 The Nucleus of a Multiprogramming System, CACM, 13, No. 4 (Apr.), 238—
241.
Эта статья описывает ядро системы RC 4000. Система представляет собой иерар-
хию взаимодействующих процессов, которые общаются между собой через почто-
вые ящики. Система обеспечивает базу программного обеспечения, на которой
можно построить разнообразные операционные системы (см. также разд. 1.4).
Бринч Хансен (Brinch Hansen Р.)
1971 Short-Term Scheduling in Multiprogramming Systems, Proc. Third ACM
Symp. Operating Systems Principles (Oct.), 101—105.
Представлено несколько алгоритмов, которые описывают работу краткосрочного
планировщика в многоуровневой схеме планирования (см. также разд. 3.4). Дано
подробное изложение алгоритмов, которое естественно подводит к описанию фак-
тической реализации.
Брон, Густавсон (Brawn В. S., Gustavson F. G.)
1968 Program Behavior in a Paging Environment, Proc. AFIPS 33, Pt. II, FJCC,
pp. 1019—1032.
Автоматическое управление памятью рассматривается с точки зрения пользова-
теля. Результаты исследования позволяют предположить, что стиль программи-
рования может быть гораздо более важным фактором для общей эффективности
страничной организации, чем алгоритм замещения страниц.
Бэр (Baer J. L.)
1973 A Survey of Some Theoretical Aspects of Multiprocessing, ACM Comput.
Surveys, 5, No. 1 (Mar.), 31—80.
Дается обзор свойств языков программирования, теоретических моделей и ана-
лизируется эффективность многопроцессорных систем. В работе имеется обширная
библиография и специальное приложение по аппаратной реализации многопрО-
цессной обработки.
Вайнберг (Weinberg G. М.)
1971 The Psychology of Computer Programming, Van Nostrand-Reinhold, Prin-
ceton, New Jersey.
В этой книге обсуждается спорный вопрос о том, не следует ли программирование
для вычислительных машин изучать как вид человеческой деятельности, исполь-
зуя методы психологии.
Вайнгартен (Weingarten А.)
1966 The Eschenbach Drum Scheme, C ACM, 9, No. 7 (July), 509—512.
В статье описана и проанализирована организация страничного барабана.
Вайсман, Стэйси (Weissman L., Stacey G. М.)
1973 An Interface System for Improving Reliability of Software Systems, Record
1973 IEEE Symp. Comput. Software Reliability, New York, pp. 136—142.
В статье описана автоматическая система организации взаимосвязи между моду-
лями. Модули при общении пользуются математическими именами, которые сис-
тема отображает в физические адреса ячеек. Адресоваться непосредственно к этим
ячейкам модули не могут.
Ван Хорн (Van Horn Е. С.)
1968 Three Criteria for Designing Computing Systems to Facilitate Debugging
CACM, 11, No. 5 (May), 360-365.
В этой статье предлагаются три критерия для оценки свойств системы; эти крите-
рии описаны на примере управления выводом информации в системе. При об-
основании этих критериев использовано понятие виртуальной машины.
Варни (Varney R. С.)
1971 Process Selection in a Hierarchical Operating Systems, Proc Third ACM Symp.
Operating Systems Principles (Oct.), pp. 106—108.
В статье предложена схема планирования процессов и описано ее применение к
структуре процессов системы.
Виноград, Морганштайн, Херман (Winograd J., Morganstein S. J., Herman R.)
1971 Simulation Studies of a Virtual Memory Time-Shared Demand Paging Ope-
rating System, Proc. Third ACM Symp. Oprating Systems Principles (Oct.),
pp. 149—155.
В статье описана имитационная модель операционной системы, обеспечивающей
работу в режиме разделения времени. Два примера моделирования обсуждаются
с точки зрения влияния размера памяти на частоту подкачек, а также с точки зре-
ния применения стратегий планирования, оказывающих предпочтение заданиям,
работающим в интерактивном режиме, по сравнению с заданиями, выполняемыми
в пакетном режиме.
Вирт (Wirth N.)
1968 PL/360—A Programming Language for the 360 Computers, J ACM, 15, No. 1
(Jan.), 37—74.
В этой статье содержится полное описание системного языка программирования
PL/360 для машин серии IBM/360.
Вирт (Wirth N.)
1969 On Multiprogramming, Machine Coding and Computer Organization, CACM
12, No. 9 (Sept.), 489—498.
Рассматриваются существующие в языках программирования структуры, с по-
мощью которых можно описывать параллельные действия, не используя явным
образом понятие прерывания. В качестве примера приведена программа на языке
PL/360, в которой использованы семафоры Дейкстры.
Вирт (Wirth N.)
1971 The Programming Language Pascal, Acta Informat., 1, Fasc. 1, 35—63.
В этой статье дается четкое и полное описание структурного языка программиро-
вания PASCAL.
Вулф (Wulf W. А.)
1969 Performance Monitors for Multiprogramming Systems, Proc. Second ACM
Symp. Operating Systems Principles (Oct.), pp. 175—181.
В этсй статье рассматривается применение мониторов отслеживания эффективно-
сти для сбора информации, которая затем должна учитываться при выборе стра-
тегии планирования. Особое внимание в статье уделено корректированию стра-
тегий распределения и изменению состава смеси заданий.
Вулф, Митчелл, Хопкинс, Хорнинг, Уэллс, Берглас, Холстед, Карас (Wulf W.,
Mitchell J., Hopkins M-, Horning J., Wells M., Berglass G., Halstead M.,
Karasz P.)
1972 Project Rosetta Stone—-An Exhibition of Language for System Implementa-
tion-Participants Guide, Dept, of Comput. Sci. Carnegie-Mellon Univ.,
Pittsburgh, Pennsylvania (Sept.).
В работе дается подробное описание проекта «Rosetta Stone», предназначенного,
для оценки языков системного программирования.
Гейнес (Gaines R. S.)
1971 An Operating System Based on the Concept of a Supervisory Computer,
Proc. Third ACM Symp. Operating System Principles (Oct.), pp. 17—23.
Дано описание и оценка небольшого супервизора, похожего на стержень системы
SUE, для операционной системы, реализованной на машине CDC 6600.
Гир (Gear С. W.)
1969 Computer Organization and Programming, McGraw-Hill, New York.
Это пособие представляет собой введение по организации вычислительных ма-
шин; рассматриваются аппаратура, ввод-вывод, ассемблер, методы сортировки,
поиска и компиляции.
Готлиб, Бородин (Gotlieb С. С., Borodin А.)
1973 Social Issues in Computing, Academic Press, New York.
Эта книга охватывает широкий круг вопросов, относящихся к влиянию вычисли-
тельных машин на общество. В частности, глава о сохранении тайны частной ин-
формации имеет отношение к материалу в разд. 7.6.
Готлиб, Мак-Эван (Gotlieb С. С., MacEwan G. Н.)
1970 System Evaluation Tools, in Software Engineering Techniques (J. N. Buxton,
B. Randell, ed.), pp. 93—99, NATO Sci. Affairs Div., Brussels.
Описано применение метода моделирования и использование мониторов на раз-
личных фазах проектирования систем-
Грехем Дж., Деннинг (Graham G. S., Denning Р. J.)
1971 Protection: Principles and Practice, Tech. Rep. No. 101, Dept, of Elec.
Enging., Princeton Univ., Princeton, New Jersey (Nov.).
Описана матричная модель доступа для организации защиты. Рассматривается
также применение данной модели для проектирования операционных систем.
Грехем Р. (Graham R. М.)
1968 Protection in an Information Processing Utility, CACM, 11, No. 5 (May)
365—369.
Описана абстрактная модель механизма защиты для системы MULTICS, которая
использует уровни, называемые «кольцами».
Грехем Р., Кленси, Деванси (Graham R. М., Clancy G. J., DeVancey D. В.)
1971 A Software Design and Evaluation System, Proc. ACM/SIGOPS Workshop
on System Performance Evaluation, pp. 200—213.
Эта статья описывает язык DES для проектирования, оценки и реализации систем.
Главная черта данной системы — это возможность получать оценки эффективности
при помощи моделирования в течение процесса проектирования.
Грис (Gries D .)
1971 Compiler Construction for Digital Computers, Wiley, New York. (Есть рус-
ский перевод: Д. Грис, Конструирование компиляторов для цифровых вы-
числительных машин, «Мир», М., 1975.)
Эта книга представляет собой введение в технологию написания компиляторов;
она включает методы грамматического разбора и генерации кода, а также содер-
жит общие соображения организационного порядка.
Дал, Дейкстра, Хоар (Dahl O.-J., Dijkstra Е. W., Hoare С. A. R.)
1972 Structured Programming, Academic Press, New York. (Есть русский перевод:
У. Дал, Э. Дейкстра, К Хоор, Структурное программирование, «Мир»,
М., 1975.)
Эта книга содержит три статьи по структурному программированию. Первая
статья Дейкстры «Заметки по структурному программированию» представляет
собой систематическое изложение метода проектирования программ «сверху
вниз». Статья Хоара «О структурной организации данных» вводит аналогичные
концепции, применимые к структурам данных. Третья статья рассматривает при-
менение этих принципов в связи с языком Симула-67.
Дейкстра (Dijkstra Е. W.)
1965 Solution to a Problem in Concurrent Programming Control, CACM, 8, No. 9
(Sept.), 569.
В этой статье дано решение проблемы взаимного исключения для п процессов,
обобщающее алгоритм Деккера, предложенный для двух процессов.
Дейкстра (Dijkstra Е. W.)
1968а Cooperating Sequential Processes, in Programming Languages (F. Genuys,
ed.), pp. 43—112, Асаdemie Press, New York. (Есть русский перевод в
сб. «Языки программирования» под ред. Ф. Женюи, «Мир», М., 1972).
В этой, ставшей теперь классической, статье по синхронизации процессов описаны
семафоры, задачи о критических участках и методы предупреждения тупиков.
Дейкстра (Dijkstra Е. W.)
1968b The Structure of the T.H.E. Multiprogramming System, CACM, 11,
No. 5 (May), 341—346.
Эта статья представляет собой краткое описание системы THE, включающее описа-
ние примененного при проектировании подхода «снизу вверх» и определение се-
мафоров.
Дейкстра (Dijkstra Е. W.)
1968с GO ТО Statement Considered Harmful, CACM, 11, No. 3 (Mar.), 147—148.
В этом знаменитом «письме к редактору» Дейкстра высказал свои принципиаль-
ные возражения против употребления оператора GO ТО.
Дейкстра (Dijkstra Е. W.)
1971 Hierarchical Ordering of Sequential Processes. Acta Informat., 1, Fasc. 2,
115—138.
Обсуждаются концепции семафоров и секретарей (т. е. мониторов Хоара) в связи
с проблемой создания недетерминированного взаимодействия аппаратных частей
виртуальной машины с синхронизацией.
Деннинг (Denning Р. J.)
1968 The Working Set Model for Program Behavior, CACM, 11, No. 5 (May),
323—333.
В этой статье Деннинга вводятся основные принципы модели рабочего множества
(см. также разд. 5.4.1)
Деннинг (Denning Р. J.)
1970 Virtual Memory, ACM Comput. Surveys, 2, No. 3 (Sept.), 153—190.
Этот обзор представляет собой развернутое обсуждение большинства аспектов
систем виртуальной памяти. Он включает очень полную библиографию по данной
теме.
Деннинг, Деннис, Лэмпсон, Хаберман, Мунц, Цикритзис (Denning Р. J.,
Dennis J. В., Lampson В. W., Habermann A. N., Muntz R. R., Tsichrit-
zic D.)
1971 An Undergraduate Course on Operating System Principles, Cosine Committee
on Education of the Nat. Acad, of Engrng., Washington, D. C.
Этот отчет, выпущенный рабочей группой VIII по вопросам обучения машинной
математике, представляет собой полный курс по операционным системам. Данный
отчет лег в основу построения нашей книги.
Деннинг, Шварц (Denning Р. J., Schwartz S. С.)
1972 Properties of the Working Set Model, CACM, 15, No. 3 (Mar.), 191—198.
Высказывается несколько математических утверждений относительно рабочих
множеств, в том числе о связи между размером рабочего множества и частотой
подкачек страниц, о вероятностном распределении размера рабочего множества
и влиянии межстраничной зависимости на размер рабочего множества.
Деннис (Dennis J. В.)
1965 Segmentation and the Design of Multiprogrammed Computer Systems, J ACM,
12, No. 4 (Oct.), 589—602.
Обсуждается несколько различных механизмов адресации, связанных с простран-
ством имен, пространством памяти и пространством адресов. Особое внимание
уделяется гибкости адресной схемы в связи с совместным использованием памяти,
защитой и динамическим распределением.
Деннис (Dennis J. В.
1969 Programming Generality, Parallelism and Computer Architecture, Proc.
IFIP Congr. 1968, pp. 484, 492, North-Holland Publ., Amsterdam.
Описывается параллелизм в системах с точки зрения схем программ.
Деннис (Dennis J. В.)
1971 Coroutines and Parallel Computation, Proc. Fifth Annu. Princeton Conf.
Information ScL and Systems, pp. 293—294.
Описывается понятие сопрограммы (Конвей, 1963) в связи с параллельно выпол-
няющимися процессами.
Деннис, Ван Хорн (Dennis J. В., Van Horn Е. С.)
1966 Programming Semantics for Multiprogrammed Computations, CACM, 9,
No. 3 (Mar.), 143—155. (Есть русский перевод в сб. «Современное програм-
мирование. Мультипрограммирование и разделение времени», «Мир», М.,
1970.)
Это одна из первых статей, описывающих терминологию и принципы мультипро-
граммных систем. Особое внимание уделяется спискам возможностей и иерархи-
ческим справочникам.
Донован (Donovan J. J.)
1972 Systems Programming, McGraw-Hill, New York. (Есть русский перевод:
Дж. Донован, Системное программирование, «Мир», М., 1975.)
Этот учебник содержит описание основанного на системах фирмы IBM подхода к
проблемам программирования ассемблеров, редакторов связей, загрузчиков,
компиляторов и операционных систем.
Доэрти (Doherty W. J.)
1970 Scheduling TSS/360 for Responsiveness, Proc. AFIPS 37, FJCC, pp. 97—111.
Путем тщательной и методической корректировки параметров в таблично управ•
ляемом планировщике системы TSS/360 было достигнуто значительное увеличение
эффективности системы. Корректировка производилась относительно размеров
рабочего множества и текущего распределения памяти. Целью работы было выпол-
нение самой корректировки; полученные результаты подробно описаны.
Зальтцер (Saltzer J. Н.)
1966 Traffic Control in a Multiplexed Computer System, MAC-TR-30. Sc. D.
Thesis, Dept, of Elec. Engrng., Cambridge, Massachusetts.
В диссертации описана схема процессора мультиплексной передачи информации
в условиях мультипрограммной мультипроцессорной системы. Предложенный в
работе контроллер, регулирующий передачи, был реализован в системе MULTICS.
Зальтцер, Джинтелл (Saltzer J. Н., Gintell J. W.)
1970 The Instrumentation of Multics, CACM, 13, No. 8 (Aug.), 495—500.
В статье описаны специальные аппаратные устройства и программные инструмен-
ты, предназначенные для оценки системы MULTICS.
Зарник (ред.), Цикритзис, Баллард, Драйер, Холт, Вайсман (Czarnik В. [editor],
Tsichritzis D., Ballard A. J., Dryer M., Holt R. C., Weissman L.)
1973 A Student Project for an Operating System Course, CSRG-29, Computer Sys-
tems Research Group, Univ, of Toronto.
Этот технический отчет включает описание проекта «игрушечной» операционной
системы 000/Z и руководство для пользователей по языку с параллельными про-
цессами TOPPS. Приводятся примеры частей системы 000/Z, написанные на
языке TOPPS.
Истон (Easton W. В.)
1971 Process Synchronization without Long-Term Interlock, Proc. Third ACM
Symp. Operating Systems Principles (Oct.), pp. 95—100.
С каждым блоком «критических» данных в системе управления файлами связыва*
ется «номер версии». Контроль может производиться по номеру версии до и после
осуществления доступа к блоку. Показано, что данный подход устраняет необхо-
димость в длительной блокировке процессов, обращающихся к файлу.
Ихбиа, Риссен (Ichbiah J. D., Rissen J. Р.)
1971 Directions de Travail pour un Atelier de Software: Rapport Preliminaire,
Compagnie Internationale Pour I’lnformatique, Paris (Oct.), pp. 3—9.
Авторы предлагают создать программное обеспечение, которое можно использо-
вать в качестве инструмента для экспериментов по конструированию надежных
программных средств.
Калингэрт (Calingaert Р.)
1967 System Performance Evaluation: Survey and Appraisal, CACM, 10, No. 1
(Jan.), 12—18.
Дано определение целей оценки вычислительных систем и описаны основные ме-
тоды анализа, моделирования и синтеза систем.
Карп, Миллер (Karp R. М., Miller R. Е.)
1969 Parallel Program Schemata, J. Comput. System Set,, 3, No. 2 (May), 147—195*
В этой довольно сложной статье представлена модель для параллельных вычисле-
ний, подобная описанной в разд. II. 2. Это одна из основных статей по вопросу о
схемах программ.
Керниган (Kernighan В. W.)
1969 Optimal Segmentation Points for Programs, Proc. Second ACM Symp. Ope-
rating Systems Principles (Oct.), pp. 47—53.
Программы моделируются графами, вершины которых представляют инструкции
или элементы данных, а дуги — переходы между ними. Описывается линейный по
времени алгоритм, который отыскивает при определенных предположениях оп-
тимальные точки деления программы при страничной обработке.
Керниган и Плафер (Kernighan В. W., Plaugher Р. J.)
1973 Programming Style for Programmers and Language Designers, Record IEEE
Symp. Comput. Software Reliability, New York, pp. 148—154.
Хорошими программами оказываются обычно программы, написанные в хорошем
стиле. Обсуждается ряд принципов щпримеров стиля программирования в отно-
шении их влияния на надежность программы.
Килберн, Эдвардс, Лэниган и Самнер (Kilburn Т., Edwards D. В. G., Lanigan
М. J., Sumner F. Н.)
1962 One-level Storage System, IRE Trans. Electron, Comput., EC-11, No. 2 (Apr.),
223—234.
В статье дается краткое описание машины «Атлас» и излагается общий метод орга-
низации виртуальной памяти с использованием оперативной памяти и барабана.
Кинг (King J. С.)
1969 A Program Verifier, Ph. D. Thesis, Dept, of Comput. Sci., Carnegie-Mel Ion
Univ., Pittsburgh, Pennsylvania.
Автор описывает структуру компилятора с подтверждением, который не только
компилирует код, но и проверяет, согласуются ли утверждения программиста с
тем, что программа фактически делает.
Киф (Keefe D. D.)
1968 Hierarchical Control Programs for Systems Evaluation, IBM Systems J.9
7, No. 2, 123—133.
Обсуждается метод проверки системных программ, при котором система работает
в непривилегированном режиме, а специальный монитор, работающий в привиле-
гированном режиме, обслуживает запросы программ на ввод-вывод и собирает
данные.
Кларк, Хорнинг (Clark В. L., Horning J. J.)
1971 The System Language for Project SUE, ACM SIGPLAN Notices, 6, No. 9
(Oct.), 79—88.
В этой статье описан язык системы SUE — язык для реализации систем, имеющий
много общего с языком PASCAL.
Клейнрок (Kleinrock L.)
1970 A Continuum of Time Sharing Scheduling Algorithms, Proc. AFIPS 36, SJCC,
pp. 453—458.
Получен класс алгоритмов планирования с помощью изменения двух параметров
линейной функции приоритетов. Дан полный анализ одного из этих алгоритмов,
названного эгоистическим круговоротом.
Кнут (Knuth D.)
1966 Additional Comments on a Problem in Concurrent Programming Control,
CACM, 9, No. 5 (May), 321—322.
Кнут описывает одну проблему, связанную с решением Дейкстры задачи взаим-
ного исключения в случае п процессов, и предлагает ее решение.
Кнут (Knuth D.)
1968 Fundamental Algorithms, The Art of Computer Programming, Vol. I, Addison
Wesley, Reading, Massachusetts. (Есть русский перевод Д. Кнут, Искусство
программирования для ЭВМ, т. I, Основные алгоритмы, «Мир», М., 1976.)
Вторая часть этой прекрасной книги представляет собой полное рассмотре-
ние структур данных и работы с ними. (См. также приложение I.)
Комо (Comeau L. W.)
1967 A Study of the Effect of User Program Optimization in a Paging System,
Proc. ACM Symp. Operating System Principles, pp. 7.
Эксперимент по влиянию программы пользователя на страничный обмен показал,
что оптимизация, проведенная пользователем, значительно улучшает общую эф-
фективность системы со страничной организацией.
Конвей (Conway М. Е.)
1963 Design of a Separable Transition Diagram Compiler, CACM, 8, No. 7
(July), 396—408.
Описаны методы проектирования компиляторов с языка КОБОЛ. Эта статья осо-
бенно хорошо известна из-за введенного в ней понятия сопрограммы.
Конвей (Conway М. Е.)
1968 How do Committees Invent?, Datamation, 14, No. 4 (Apr.), 29—32.
Выдвигается тезис о том, что структура системы напоминает структуру организа-
ции, которая ее производит. Автор обсуждает также вопрос о том, как следовало
бы использовать это наблюдение при определении структуры группы проектиро-
вания.
Конвей, Максвелл, Морган (Conway R. W., Maxwell W. L., Morgan H. L.)
1972 On the Implementation of Security Measures in Information Systems, CACM,
15, No. 4 (Apr.), 211—220.
Определена матричная модель обеспечения безопасности, и показано, что ее можно
применить для моделирования некоторых существующих систем обеспечения бе-
зопасности.
Корбато (Corbato F. J.)
1969 PL/I as a Tool for System Programming, Datamation, 15, No. 5 (May), 68—76.
Описаны причины, по которым язык PL/I был выбран в качестве языка програм-
мирования при написании проекта MULTICS. Эта статья является хорошим до-
полнительным материалом для разд. 9.2.
Корбато, Зальтцер (Corbato F. J., Saltzer J. Н.)
1969 Some Considerations of Supervisor Program Design for Multiplexed Computer
Systems, Proc. IFIP Congr. 1968, pp. 315—321, North-Holland Publ., Am-
sterdam.
Обсуждаются проблемы, относящиеся к сложным системам, а также проблемы,
возникающие при организации совместного использования информации. Особое
внимание уделено системам разделения времени.
Коффман (Coffman Jr. Е. G.)
1969 Analysis of a Drum Input/Output Queue under Scheduled Operation in a
Paged Computer System, J ACM, 16, No. 1 (Jan.), 73—90.
В статье используются математические модели, с помощью которых измеряются
загрузка, средняя длина очереди и среднее время ожидания для барабанов, ис-
пользуемых в качестве вспомогательной памяти.
Коффман, Вариан (Coffman Jr. Е. G., Varian L. С.)
1968 Further Experimental Data on the Behavior of Programs in a Paging Environ-
ment, CACM, 11, No. 7 (July), 471—474.
По нескольким программам подытоживаются экспериментальные результаты сме-
ны страниц при различных алгоритмах замещения (см. также разд. 5.4.4.1).
Коффман, Деннинг (Coffman Jr. Е. G., Denning Р. J.)
1973 Operating System Theory, Prentice-Hall, Englewood Cliffs, New Jersey.
В работе представлены различные аспекты моделирования и анализа проблем,
возникающих в операционных системах. Эта книга является хорошим справоч-
ником по аналитическим методам решения проблем распределения ресурсов.
Коффман, Клейнрок (Coffman Jr. Е. G., Kleinrock L.)
1968 Computer Scheduling Measures and Their Countermeasures, Proc. AFIPS 32,
SJCC, pp. 11—21.
Проанализированы основные методы планирования заданий и указаны тактики
пользователя, при которых наилучшим образом используются слабые стороны
каждого метода.
Коффман, Райэн (Coffman Jr. Е. G., Ryan Jr. Т. А.)
1972 A Study of Storage Partitioning Using a Mathematical Model of Locality
CACM, 15, No. 3 (Mar.), 185—190.
Представлена математическая модель для выбора размера части памяти при стра-
ничной организации. Показано, что при малых размерах рабочего множества го-
дится разбиение на части фиксированного размера.
Коффман, Ренделл (Coffman Jr. Е. G., Randell В.)
1971 Performance Prediction for Extended Paged Memories, Acta Informat., 1,
Fasc. L 1—13.
Авторы разрабатывают модель для увеличения размеров страничной памяти.
При заданной последовательности ссылок на страницы в программе их аналитиче-
ский метод позволяет предсказать эффективность алгоритма смены страниц с уве-
личением числа физических страниц памяти.
Коффман, Элфик, Шошани (Coffman Jr. Е. G., Elphick М., Shoshani А.)
1971 System Deadlocks, ACM Comput. Surveys, 3, No. 2 (June), 67—78.
Этот обзор кратко описывает некоторые из основных работ, посвященных тупикам в
системах с повторно используемыми ресурсами. Выявление тупиков рассматрива-
ется для случаев, когда заранее известны точные потребности процесса в ресурсах,
когда заранее известны только его максимальные требования и когда требования
на ресурсы не известны до момента запроса.
Кук и Лори (Kuck D. J., Lawrie D. Н.)
1970 The Use and Performance of Memory Hierarchies: a Survey, in Software En
gineering, Vol. 1, pp. 45—78, Academic Press, New York*
Иерархии памяти обсуждаются с точки зрения структуры, экономичности, пове-
дения программ и влияния на общую производительность системы. Приводится
ряд экспериментальных результатов.
Куртуа, Хеймане, Парнас (Courtois Р. J., Heymans F., Parnas D. L.)
1971 Concurrent Control with «Readers» and «Writers», CACM, 14, No. 10 (Oct.),
667—668.
Представлены два решения проблемы синхронизации «читающих» и «пишущих»
процессов (о которых говорится в упражнении 2.20 к гл. 2).
Липтэй (Liptay J. S.)
1968 Structural Aspects of the System/360 Model 85: II The Cache, IBM Systems J.9
7, No. 1, 15—21.
Описывается кэш-память — сверхбыстрая память, буферная между оперативной
памятью и центральным процессорным устройством для модели IBM 360/85.
Лисков (Liskov В. Н.)
1972 The Design of the Venus Operating System, С4СМ, 15, No. 3 (Mar.), 144—149.
В статье представлено описание существенных характеристик программного обе-
спечения системы «Венера» (см. также гл. 10).
Лондон (London R. L.)
1970 Proving Programs аге Correct: Some Techniques and Examples, BIT, 10,
168—182.
Описывается пять методов доказательства правильности программ, приводятся
примеры для каждого метода.
Лукаш (Lucas Н. С.)
1971 Performance Evaluation and Monitoring, ACM Comput. Surveys, 3, No. 3
(Sept.), 79—91.
В статье дается нетривиальный обзор большинства хорошо известных методов
оценки производительности.
Лукони (Luconi F. L.)
1968 Asynchronous Computational Structures, MAC-TR-49. Ph. D. Thesis Dept,
of Elec. Engrng., M. I. T., Cambridge, Massachusetts.
Представлена модель «вычислительных схем» для параллельных систем. Дана тео-
ретическая разработка определенных свойств, связанных с детерминизмом и вза-
имосвязью процессов.
Льюис, Шедлер (Lewis Р. A. W., Shedler G. S.)
1971 A Cyclic-queue Model of System Overhead in Multiprogrammed Computer
Systems, J ACM, 18, No. 2 (Apr.), 199—220.
Описывается сложная вероятностная модель мультипрограммной системы с вы-
зовом страниц по запросу.
Лэмпсон (Lampson В. W.)
1968 A Scheduling Philosophy for Multiprocessing Systems, CACM, 11, No. 5
(May), 347—360.
Рассматриваются основные понятия защиты и планирования процессов, включая
концепции возможностей, двухуровневое планирование и аппаратную реализа-
цию алгоритмов планирования.
Лэмпсон (Lampson В. W.)
1969 Dynamic Protection Structures, Proc. AFIPS 35, FJCC, pp. 27—38.
Приведена общая модель просмотра доменов, возможностей и ключей доступа с
обсуждением как теоретических, так и практических аспектов.
Лэмпсон (Lampson В. W.)
1971 Protection, Proc. Fifth Annu. Princeton Conf. Information Sci. and Systems,
pp. 437—443.
В этой статье развивается большинство основных абстрактных понятий защиты.
Обсуждаются модели защиты для доменов, матриц доступа, возможностей и за-
щиты памяти.
Мак-Дугал (Mac Dougall М. Н.)
1970 Computer System Simulation: an Introduction, ACM Comput. Surveys, 2.
No. 3 (Sept.), 191—209.
Обсуждаются общие методы моделирования и модель для имитации мультипро-
граммной системы, основанной на применении дисков. Статья содержит аннотиро-
ванную библиографию по проблеме моделирования вычислительных систем.
Мак-Илрой (McIlroy М. D.)
1969 Mass Produced Software Components, in Software Engineering (P. Naur and
B. Randell, eds.) pp. 138—155, NATO Sci. Affairs Div., Brussels.
В этой неформальной статье обсуждается пригодность стандартных модулей для
систем программного обеспечения и исследуются вопросы, связанные с производ-
ством таких модулей.
Мак-Келлар, Коффман (McKellar А. С., Coffman Jr. Е. G.)
1969 Organizing Matrices and Matrix Operations for Paged Memory Systems,
CACM, 12, No. 3 (Mar.), 153—165.
Переупорядочивая расположение матриц по страницам авторы добились эффект-
ных улучшений в условиях страничной организации памяти.
Мак-Киман, Хорнинг, Вортман (McKeeman W. М., Horning J. J., Wortman D. В.)
1970 A Compiler Generator, Prentice-Hall, New Jersey.
Введение в методы компиляции, основанные на системе разработки компиляторов
XPL.
Мак-Кинни (McKinney J. М.)
1969 A Survey of Analytical Time-Sharing Models, ACM Comput. Surveys, 1,
No. 2 (June), 105—116.
В этой статье дается обзор моделей планирующих алгоритмов с использованием
очередей; рассматриваются правило круговорота, очереди с передним и задним
планом и очереди с обратной связью. В заключение статьи дается аннотированная
библиография.
Маршленд, Тартар (Marshland Т . A., Tartar J.)
1973 A Course of Minicomputer Systems, ACM SIGCSE Bull., 5, No. 1 (Feb.),
153—156.
Описывается схема курса по мини-машинам. Обсуждаются цели курса, области
исследований по созданию новых машин и выбор подходящей мини-машины.
Мерфи (Murphy J. Е.)
1968 Resource Allocation with Interlock Detection in a Multi-Task System, Proc.
AFIPS 33, Pt. II, FJCC, pp. 1169—1176.
Обсуждается техника организации очередей и метод распределения ресурсов, ос-
нованный на использовании специальных матриц. Представлен алгоритм выявле-
ния тупиковой ситуации, использующий эту схему.
Мили (Mealy G. Н.)
1967 Operating Systems (Excerpts), in Programming Systems and Languages
(S. Rosen, ed.), pp. 516—534, McGrow-Hill, New York.
Работа представляет собой очень общее, ориентированное на системы фирмы IBM,
обсуждение операционных систем с упором на ввод-вывод и супервизор.
Мили (Mealy G. Н.)
1969 The System Design Cycle, Proc. Second ACM Symp. Operating Systems Prin-
ciples (Oct.), pp. 1—7.
В статье дается обзор тех проблем развития систем, которые связаны с организа-
ционными трудностями. Обсуждается закон Конвея. Материал связан с разд. 8.4.
Мили, Витт, Кларк (Mealy G. Н., Witt В. I., Clark W. А.)
1966 The Functional Structure of OS/360, IBM Systems J., 5, No. 1, 2—51.
Представлен общий обзор операционной системы OS для системы IBM/360.
Миллс (Mills Н.)
1971 Top Down Programming in Large Systems, in Debugging Techniques in Large
Systems (R. Rustin, ed.), pp. 41—55, Prentice-Hall, Englewood Cliffs, New
Jersey.
В качестве части общего подхода к разработке программ обсуждаются два основ-
ных понятия структурного программирования, а именно: последовательное уточ-
нение и простые управляющие структуры.
Миллс (Mills Н.)
1972 Mathematical Foundations of Structural Programming, N. FSC72-6012,
IBM Federal Systems Div.
Статья посвящена результату, показывающему, что любая программа может быть
написана с использованием только управляющих структур IF—THEN—ELSE,
BLOCK и DO—UNTIL (т. e. без оператора GOTO). Кроме того, приводятся основ-
ные утверждения, необходимые для доказательства правильности программы,
построенной сверху вниз с использованием этих управляющих структур.
Миллс (Mills Н.)
1973 On the Development of Large Reliable Programs, Record 1973 IEEE Symp.
Comput. Software Reliability, New York, pp. 155—159.
Дается обзор методов структурного программирования и рассматривается их
влияние на построение больших, надежных систем программного обеспечения.
Мореноф, Мак-Лин (Morenoff Е., McLean J. В.)
1967 An Approach to Standardizing Computer Systems, Proc. ACM Nat. Conf.,
22nd, pp. 527—536.
Ввиду того, что на многих установках часто изменяется аппаратура, существенной
является проблема программной совместимости для разных машин. Авторы иссле-
дуют эту проблему и указывают некоторый путь к возможной стандартизации.
Морзе (Morse Р. М.)
1958 Queues, Inventories, and Maintenance, Wiley, New York.
Это руководство представляет собой один из ранних обзоров теории очередей.
Мэдник, Олсоп (Madnik S. Е., Alsop J. W.)
1969 A Modular Approach to File System Design, Proc. AFIPS 34, SJCC, pp. 1—14.
Описывается многоуровневый подход к построению системы управления файлами.
Он является основой структуры, представленной в гл. 6.
Мэттсон, Джекси, Слутц, Трейджер (Mattson R., Gecsei J., Slutz D., Traiger I.)
1970 Evaluation Techniques for Storage Hierarchies, IBM Systems J., 9, No. 2,
Исследуются иерархии памяти в условиях страничного распределения памяти.
Рассматриваются свойства одного класса алгоритмов замещения, именуемых
«стековыми алгоритмами»; доказывается оптимальность одного из стековых алго-
ритмов.
Наур, Ренделл (Naur Р., Randell В. (eds.).
1969 Software Engineering, NATO Sci. Affairs Div., Brussels.
В данном томе дается краткий обзор рабочих документов, дискуссий и семинаров
конференции НАТО 1968 года по проектированию программного обеспечения.
Нейман (Neumann Р. G.)
1969 The Role of Motherhood in the Pop Art of System Programming, Proc. Second
ACM Symp. Operating Systems Principles (Oct.), pp. 13—18.
Обсуждаются разумные принципы проектирования и реализации систем. Пред-
ставлено около дюжины таких принципов и приведены причины, по которым эти
принципы часто игнорируются. Изложение кратко, занимательно и информативно.
Оппенгеймер, Вайцер (Oppenheimer G., Weizer N.)
1968 Resource Management for a Medium Scale Time-Sharing Operating System,
CACM, 11, No. 5 (May), 313—322.
Обсуждаются проблемы планирования, распределения ресурсов и управления
памятью в связи с разработкой операционной системы разделения времени для
RCA Spectra 70/46.
Органик (Organick Е. I.)
1972 The Multics System: An Examination of its Structure, MIT Press, Cambridge,
Massachusetts.
В этом очень четком описании собрана воедино информация о системе MULTICS.
Оно относится к числу лучших опубликованных описаний известных операцион-
ных систем.
Органик (Organick Е. I.)
1973 Computer System Organization—The B5700/B6700 Series, Academic Press,
New York.
В этой книге описывается тесная взаимосвязь между структурой программного
обеспечения и архитектурой аппаратуры машин фирмы Burroughs. Как часть уни-
фицированного подхода к организации вычислительных систем обсуждаются сег-
ментация, структурирование процессов, прерывания и команды работы со стеком.
Панкхерст (Pankhurst R. J.)
1968 Programm Overlay Techniques, CACM, 11, No. 2 (Feb.), 119—125.
Представлено описание автоматических, полуавтоматических и ручных методов
реализации перекрытий программ. Рассматриваются также некоторые вопросы
реализации.
Парнас (Parnas D. L.)
1971 Information Distribution Aspects of Design Methodology, Proc. IFIP Congr.
1971, Booklet TA-3, pp. 26—30.
Степень связи между модулями измеряется числом сведений друг о друге, которы-
ми модули должны располагать. Основываясь на этой предпосылке, автор обсуж-
дает ее влияние на проектирование и документацию систем программного обеспе-
чения.
Парнас, Дарринджер (Parnas D. L., Darringer J. А.)
1967 SODAS and a Methodology for System Design, Proc. AFIPS 31, FJCC,
pp. 449—474.
В этой статье обсуждается подход «сверху вниз» к проектированию систем приме*
нительно к языку проектирования и моделирования систем—SODAS. Статья со-
держит обширные примеры по использованию такого подхода.
Пул, Вейт (Poole Р. С., Waite W. М.)
1969 Machine Independent Software, ACM Symp. Operating Systems Principles
(Oct.), 19—24.
Для разработки системы написания машинно-независимого программного обе-
спечения применяется моделирование абстрактных машин и методов макрообра-
ботки. Показана эффективность реализованной системы в нескольких приложениях
по переброске программного обеспечения с машины на машину.
Райс, ван Дам (Rice D. Е., van Dam А.)
1971 An Introduction to Information Structures and Paging Considerations for
Online Text Editing Systems, Advances in Information System Sci., 4, 93—159.
Авторы рассматривают вопросы организации памяти, такие, например, как выбор
размера страниц или сравнение страничной и сегментной организаций памяти
в свете собственного опыта реализации систем для редактирования текста.
Ренделл (Randell В.)
1968 Towards a Methodology of Computing System Design, in Software Engineering
(P. Naur and B. Randell, eds.), pp. 204—208, NATO Sci. Affairs Div., Brussels.
В статье с помощью структуры, разработанной Цурхером и Ренделлом [19691 для
проектирования «сверху вниз» и «снизу вверх», сравниваются подход к проектиро-
ванию, развитый Дейкстрой в проекте THE, и подход, определяемый языком
SODAS, предложенным Парнасом и Дарринджером.
Ренделл, Кюнер (Randell В., Kuehner С. J.)
1968 Dynamic Storage Allocation Systems, CACM, 11, No. 5 (May), 297—306.
Статья содержит обзор приемов динамического распределения памяти. Описаны
методы адресации, используемые в семи широко известных системах.
Родригес (Rodriguez J. Е.)
1967 A Graph Model for Parallel Computation, MAC-TR-G4. Ph. D. Thesis,
Dept, of Elec. Engrng., M. I. T., Cambridge, Massachusetts (Sept.).
В диссертации рассмотрена и проанализирована модель «графа программы» для
параллельных вычислений. Основная отличительная черта этого метода состоит
в том, что в вершину графа, определяющую операцию, неявно включается и счетчик
команд (см. также разд. II. 2).
Розин (Rosin R. F.)
1969 Supervisory and Monitor Systems, ACM Comput. Surveys, 1, No. 1 (Mar.),
Эта статья представляет собой обзор операционных систем в историческом аспекте.
Основной упор делается на возможности, предоставляемые системами, а не на
их внутреннюю структуру.
Роуз (Rose С. S.)
1972 LOGOS and the Software Engineer, Proc. AFIPS41, Pt. I, FJCC, pp. 311—323.
Дается общее представление о проекте LOGOS, определяющем программное обе-
спечение для проектирования аппаратного и программного оборудования. Под-
робно описана теоретическая система представления разрабатываемого обеспе-
чения в форме графа.
Севсик (Sevcik К. С.)
1971 The Use of Service Time Distributions in Scheduling, Ph. D. Thesis, Inst,
for Comput. Res., Univ, of Chicago, Chicago, Illinois.
В книге проводится теоретический анализ оптимальных и близких к оптимальным
стратегий планирования для одного процессора. Эти стратегии рассматриваются
при самых разнообразных предположениях. В частности, описана оптимальная
стратегия, состоящая в так называемом «выборе наименьшего ранга», которая ми-
нимизирует потери и максимизирует количество услуг.
Севсик, Атвуд, Грушков, Холт, Хорнинг, Цикритзис (Sevcik К- С., Atwood J. W.,
Grushcow М. S., Holt R. С., Horning J. J., Tsichritzis D.)
1972 Project SUE as a Learning Experience, Proc. AFIPS 41, Pt. I , FJCC
pp. 331—339.
Рассматриваются различные проектные решения, которые могут применяться
при конструировании операционных систем. Дается краткое описание конкретных
конструкций, имеющихся в системе SUE.
Симан, Линд, Уилсон (Seaman Р. Н., Lind R. A., Wilson Т. L.)
1966 An Analysis of Auxiliary Storage Activity, IBM Systems J.,5, No. 3, 158—170.
Модель организации очередей для систем периферийной памяти с прямым доступом
использована для получения оценок загруженности устройств, времени ответа
и длины очередей.
Сноудон (Snowdon R. А.)
1972 PEARL: An Interactive System for the Preparation and Validation of Structu-
red Programs, ACM SIGPLAN Notices, 7, No. 3 (Mar.), 9—12.
В этой статье описана система, которая предназначается для того, чтобы помочь
программисту убедиться в непротиворечивости каждого уровня уточнения в про-
цессе программирования методом «сверху вниз».
Сэйерс (ред.) (Sayers А. Р. (ed.))
1971 The Comtre Corp. Operating Systems Survey, Auerbach, Princeton, New
Jersey.
Дается обзор основных понятий и возможностей, связанных с операционными
системами; описано четырнадцать реальных операционных систем.
Сэйр (Sayre D.)
1969 Is Automatic ‘Folding’ of Programs Efficient Enough to Replace Manual?,
CACM, 12, No. 12 (Dec.), 656—660.
В статье сравнивается производительность двух методов: подкачки страниц по
запросу и традиционного метода перекрытий. Показано, что подкачка по запросу
более выгодна с точки зрения стоимости и гибкости.
Сэммет (Sammet J. Е.)
1971 A Brief Survey of Languages Used in Systems Implementation, ACM
SIGPLAN Notices, 6, No. 9 (Oct.), 1—19.
В статье обсуждаются основные вопросы, связанные с выбором языка высокого
уровня для реализации операционной системы. Описано несколько специализи-
рованных языков и приведены примеры систем, написанных на этих языках.
Тейчроу, Сайани (Teichrow D., Sayani Н.)
1971 Automation of System Building, Datamation, 17, No. 16 (Aug. 15), 25—30.
Эта статья представляет собой неформальное введение в проект ISDOS (Система
Проектирования и Оптимизации Информационных Систем). Назначение проекта —
автоматизировать, насколько возможно, проектирование систем и процесс их реа-
лизации.
Тернбул (Turnbull С. J. М.)
1972 A Comparative Analysis of Several Disk Scheduling Algorithms, Tech. Rep.
CSRG-16, Comput. Systems Res. Group, Univ, of Toronto, Toronto.
В книге дан анализ нескольких стратегий планирования для дисков. Показано,
что результаты этого анализа согласуются с данными, полученными Тиори и Пин-
кертоном [1972] с помощью моделирования.
Тиори, Пинкертон (Теогеу Т. J., Pinkerton Т. В.)
1972 A Comparative Analysis Of Disk Scheduling Policies, CACM, 15, No. 3 (Mar.),
177—184.
С помощью аналитических и имитационных моделей оцениваются пять стратегий
планирования для дисков с подвижными головками. Эти стратегии сравниваются
по среднему времени поиска и среднему времени ожидания и выбирается наилуч-
шая общая стратегия.
Томпсон, Ритчи (Thompson К., Ritchie D. М.)
1973 The Unix Time-Sharing System, Fourth Symposium on Operating System
Principles (Oct.).
В этой статье описаны существенные черты системы разделения времени Unix
для машин DEC PDP-11/40 и 11/45. Описание иерархической организации файлов
этой системы имеет непосредственное отношение к материалу гл. 6.
Уилкс (Wilkes М. V.)
1965 Slave Memories And Dynamic Storage Allocation, IEEE Trans. Computers,
14, No. 4 (Apr.), 270—271.
Эта статья представляет собой описание одного из ранних опытов реализации не-
большой кэш-памяти, предназначенной для уменьшения среднего времени выбор-
ки (см. также Кук и Лори [1970]).
Уилкс (Wilkes М. V.)
1968 Time Sharing Computer Systems, Amer. Elsevier, New York. (Есть русский
перевод: M. Уилкс, Системы с разделением времени, «Мир», М., 1972).
В книге дано краткое описание систем с разделением времени с точки зрения поль-
зователя. Несколько подробнее освещены организация внутренней памяти и струк-
туры файлов.
Уилкс (Wilkes М. V.)
1969 A Model for Core Space Allocation in a Time-Sharing System, Proc. AFIPS 34,
SJCC, pp. 265—271.
В статье описана структура памяти с использованием принципа трубопровода.
Стратегия распределения памяти, избегающая перекачки во вспомогательную па-
мять и обратно (swapping) заданий, не требующих много процессорного времени,
позволяет, по-видимому, сократить накладные расходы по перекачке информации.
Фабри (Fabry R. S.)
1973 The Case for Capability-Based Computers, Fourth Symposium on Operating
System Principles (Oct.).
В этой статье предлагается широко использовать аппарат «возможностей» для
реализации адресации в вычислительной системе. Приведя аргументы, доказыва-
ющие выгодность такой структуры, автор высказывает соображения по реализации
машины, основанной на возможностях.
Флойд (Floyd R. W.)
1971 Toward the Interactive Design of Correct Programs, Proc. IFIP 1971, Booklet
TA-1, pp. 1—4.
Приводится гипотетическая беседа между программистом и интерактивным кор-
ректором программ. В заключение автор высказывает соображения о том, что мог
бы делать возможный корректор программ.
Фонтао (Fontao R. О.)
1971 A Concurrent Algorithm for Avoiding Deadlocks, Proc. Third ACM Symp.
Operating Systems Principles (Oct.), pp. 72—79.
Описан алгоритм для предотвращения тупиков, который выполняется параллельно
с обслуживаемым им процессом. Алгоритм работает с таблицей безопасных состоя-
ний, которая обновляется при выполнении запросов ресурсов и освобождении
ресурсов.
Фостер (Foster С. С.)
An Unclever Time-Sharing System, ACM Comput. Surveys, 3, No. 1 (Mar.),
23—48.
Описана небольшая система разделения времени UMASS-2 для машины CDC 3600.
Фуллер, Баскет (Fuller S. Н., Baskett F.)
1972 An Analysis of Drum Storage Units, Tech. Rep. No. 26, Digital Systems Lab.,
Stanford Electron. Lab. Stanford Univ., Stanford, California (Aug.).
С помощью вероятностной модели анализируются алгоритмы планирования ра-
боты барабана по принципу FIFO, т. е. «первым пришел — первым ушел», и по
принципу «с наименьшим временем задержки — первым».
Фуш, Джексон (Fuchs Е., Jackson Р. Е.)
1970 Estimates of Distributions of Random Variables for Certain Computer Com-
munications Traffic Models, CACM, 13, No. 12 (Dec.), 752—757.
Предложена модель взаимодействия между пользователем и вычислительной ма-
шиной и показано, что поведение модели согласуется с измерениями на реальных
системах.
Хаберман (Habermann A. N.)
1969 Prevention of System Deadlocks, CACM, 12, No. 7 (July), 373—377, 385.
Описано несколько алгоритмов по предотвращению тупиков, использующих мо-
дель состояния распределения ресурсов. В частности, формализованы понятия
безопасных состояний и безопасных переходов.
Хаберман (Habermann A. N.)
1972 Synchronization of Communicating Processes, CACM, 15, No. 3 (Mar.)
171—176.
Для формализации аппарата синхронизации процессов используется отношение
инвариантности. При помощи данного формализма доказываются некоторые свой-
ства общающихся друг с другом процессов.
Хавендер (Havender J. W.)
1968 Avoiding Deadlock in Multitasking Systems, IBM Systems J., 7, No. 2, 74—84.
Представлены методы, которые используются для устранения тупиков в системе
OS/360 MVT на машинах IBM/360.
Хебалкар (Hebalkar Р. G.)
1970 Coordinated Sharing of Resources in Asynchronous Systems, Record Project
MAC Conf. Concurrent Systems and Parra lei Comput., Woods Hole, Massa-
chusetts, pp. 151—168.
Для рассмотрения связанных с тупиками свойств систем используется модель,
похожая на сети Петри; заранее известно частичное описание поведения процессов.
Хоар (Hoare С. A. R.)
1969 An Axiomatic Approach to Computer Programming, CACM, 12, No. 10 (Oct.),
576—580.
Определен набор аксиом и правил вывода для программ. Эти понятия применяются
к ручной проверке простой программы.
Хоар (Hoare С. A. R.)
1971 Proof of a Program: FIND, CACM, 14, No. 1 (Jan.), 39—45.
При доказательстве правильности одного алгоритма поиска автор развивает об-
щий метод для ручного доказательства правильности программ.
Хоар, Перро (Hoare С. A. R., Perrot R. Н.)
1972 Operating Systems Techniques, Academic Press, New York.
Книга содержит труды Международного семинара по технологии операционных
систем, который состоялся в Белфасте в 1971 году. Включены также выдержки из
дискуссий.
Холт А., Коммонер (Holt A. W., Commoner F.)
1970 Events and Conditions, Record Project MAC Conf. Concurrent Systems and
Parrallel Comput., Woods Hole, Massachusetts, pp. 3—52.
Даны описание и анализ сетей Петри, а также показано их применение к решению
некоторых простых задач, включая параллельные действия.
Холт Р. (Holt R. С.)
1972 Some Deadlock Properties of Computer Systems, ACM Comput. Surveys,
4, No. 3 (Sept.), 179—195.
Для построения алгоритмов выявления и предотвращения тупиков используется
несколько моделей теории графов (см. также разд. 2.7 и II. 3).
Холт Р., Кинред (Holt R. С., Kinread R.)
1972 Teaching and Using High Level Concurrent Programming, Proc. Canad.
Comput. Conf., Montreal, pp. 214202—214212.
Вводится язык высокого уровня TOPPS, допускающий параллельное выполнение
процессов. Используя язык TOPPS, авторы описывают, каким образом может
вестись обучение основным принципам параллельного программирования.
Хорнинг, Ренделл (Horning J. J., Randell В.)
1973- Process Structuring, ACM Comput. Surveys, 5, No. 1 (Mar.), 5—30.
Эта статья дает точные определения многим терминам, относящимся к параллель-
ным процессам. Рассматриваются также многие понятия структур систем, такие,
как виртуальная память и уровни абстракции.
Хоффман (Hoffman L. J.)
1969 Computers and Privacy: A. Survey, ACM Comput. Surveys, 1, No. 2 (June).
85-104. 7
Обсуждаются юридические и технические проблемы, относящиеся к тайне частной
информации. Статья включает обширную аннотированную библиографию.
Хуберман (Huberman В. J.)
1970 Principles of Operation of the Venus Microprogram, MITRE Tech. Reo.
MTR-1843, The MITRE Corp., Bedford, Massachusetts.
В этом отчете детально описаны микропрограммная и аппаратная части виртуаль-
ной машины системы «Венера».
Цурхер, Ренделл (Zurcher F. W., Randell В.)
1969 Intcrative Multi-Level Modeling —A Methodology for Computer System
Design, Proc. IFIPCongr. 1968, pp. 867—871, North-Holland Publ., Amster-
dam.
Это классическая статья, описывающая подход к проектированию систем по прин*
ципу «сверху вниз».
Шарп (Sharpe W. F.)
1969 The Economics of Computers, Columbia Univ. Press, New York.
Книга начинается с предварительных сведений из экономики, имеющих отноше-
ние к экономике вычислительных машин. Далее подробно обсуждаются экономи-
ческие вопросы, связанные с приобретением и использованием вычислительных
машин.
Шлутц (Slutz D. R.)
1968 The Flow Graph Model Of Parallel Computation, MAC-TR-53, Ph. D. Thesis,
Dept, of Elec. Engrng., M. I. T., Cambridge, Massachusetts.
В этой книге модифицированный вариант схем параллельных программ [Карп и
Миллер, 1969] рассматривается с точки зрения детерминированности, эквивалент-
ности и преобразований, сохраняющих эквивалентность.
Шоу, Вайдерман (Shaw А. С., Weiderman N. Н.)
1971 A Multiprogramming System for Education and Research, Proc. IFIP Congr.
1971, Booklet TA-7, pp. 110—114.
Авторы описывают смоделированную на языке высокого уровня простую машину,
которую можно использовать в качестве базы для небольшой операционной сис-
темы. Эта машина применяется как в педагогических, так и в исследовательских
целях.
Шрёдер, Зальтцер (Schroeder М. D., Saltzer J. R.)
1971 A Hardware Architecture for Implementing Protection Rings, Proc. Third
ACM Symp. Operating Systems Principles (Oct.), pp. 42—54.
В статье обсуждается принцип колец защиты в сегментированном адресном про-
странстве, причем вопросам, связанным с аппаратным оборудованием, уделяется
несколько больше внимания.
Эбейт, Дубнер (Abate J., Dubner Н.)
1969 Optimizing the Performance of a Drum-Like Storage, IEEE Trans. Computers,
18, No. 11 (Nov.), 992—997.
Анализируется устройство памяти с неподвижными головками (головка на до-
рожку) применительно к организации очередей по принципу «с наименьшим вре-
менем ожидания при вращении — первым». Данная работа была написана в связи
с предложенным недавно аппаратным устройством, работа которого планируется
в соответствии с этим алгоритмом. Дано описание системы и представлен^ анали-
тическая оценка средней длины очереди и времени ожидания.
Элсберг, Миллс (Alsberg Р. A. Mills С. R.)
1969 The Structure of the ILLIAC IV Operating System, Proc. Second ACM Symp.
Operating Systems Principles (Oct.), 92—96.
Описана операционная система для матричной машины ILLIAC IV. В вычисли-
тельную систему входит машина Burroughs В6500, которая выполняет большую
часть функций операционной системы. Уникальное оборудование, которым осна-
щена эта система, делает описание особенно интересным.
Элспас, Грин, Левит (Elspas В., Green М. W., Levitt К- N.)
1971 Software Reliability, Computer J. 4, No. 1 (Jan.—Feb.), 21—27.
В связи с надежностью программного обеспечения обсуждаются основные аспек-
ты проектирования языков и проверки правильности программ.
Элспас, Левит, Уолдингер, Вейкман (Elspas В., Levitt К. N., Waldinger R. J.,
Wakeman А.)
1972 An Assessment of Techniques for Proving Program Correctness, ACM Comput.
Surveys, 4, No. 2 (June), 97—147.
В этом обширном обзоре приводятся как теоретические основания, так и практиче-
ские соображения по доказательству правильности программ, выполняемому руч-
ным и автоматическим способами.
Эрл, Бюджли (Earl D. Р., Bugely F. L.)
1969 Basic Time-Sharing: A System of Computing Principles, Proc. Second ACM
Symp. Operating Systems Principles (Oct.), 75—79.
Эта статья представляет собой попытку систематизировать некоторые определе-
ния и принципы проектирования операционных систем.
IBM System/360rOperating System: Concepts and Facilities, Form C28-6535-0. Data
Processing Div., IBM Corp., White Plains, New York, 1965.
Это документ, представляющий собой введение в операционную систему для се-
мейства машин IBM/360.
ПРЕДМЕТНЫЙ УКАЗАТЕЛЬ
Абстракция 202
Абстракции уровень 203
Адрес 17
Алгоритм банкира
— Деккера 50
— ОРТ 135
— планирования 77
— FB 85—86
— HPF 79-82
— RR 82-84
Аномалия Биледи 139—140
Аппаратное оборудование
Арифметическое устройство 17
Ассемблер 20
Ассоциативная память 289
Ассоциативный регистр 116
Базисная система управления файла-
ми 155, 159—162
Базовый адрес сегмента 106
Базовый регистр 95
Бит защиты 106, 109, НО
Блок 151
— управления устройством 18
Блокировка памяти 48—50
Буферизация 20
Граф повторно используемых ресурсов
299-302
— потока данных 294
— управления 294
Действие 38
Дескриптор процесса 40
— файла 155, 159, 160
Диаграмма переходов 293
Динамическое установление связей
117—120
Дисковая система ввода-вывода 157—
158
Диспетчер 86
Долгосрочный планировщик 86
Домен 180
Доступность 247
Загрузчик 95—96
Задание 72
— активное 74
Запись 21, 150
Записи поле 150
Запрос 165
Защита 176—196
Виртуальная машина 204—205
— память 122—145
Внешняя ссылка 94
Возможность 180, 263—264
Время доступа 18
— ответа 247
— поиска 99
— прохождения 73, 247
Вспомогательная память 17
Вытеснение страниц 132—136
Вычислительная схема 294—298
Именующая функция 92, 99
Инвертированный файл 166
Интерпретатор 20
Интерфейс 21
Главный справочник 163, 169—170
Голова списка 283
Граница 106
Канал 18
Квантование времени 76
Ключ 165
— частичный 165
Команда 17
Компилятор 20
Косвенная адресация 283
Краткосрочный планировщик 86
Критерии производительности 247
— эффективности 247
Критический участок 44
Круговорот 82—84
— со смещением 84
Кэш 124
Логическая система управления файла-
ми .155, 162—164 *
Локализованность 137
Менеджер канала 157
Метод доступа 155, 165—168
----базисный 167
----последовательный 167
---- прямой 167
---- с очередями 167
Метод проектирования сверху вниз
212-215
----снизу вверх 208—210
Методы оценки эффективности систе-
мы 248—254
-------- аналитические 248—249
-------имитационные 253—254
-------эмпирические 250—253
Многосвязный список 284
Многоуровневая память 123—125
Многоуровневое планирование 86—89
Модуль загрузки 96
Монитор 60, 252
— защиты 178
— Хоара 60—64
Мультипрограммирование 74—75
Мультисписок 166
Набор переменных состояния 38
Начальное состояние 38
Обслуживающая программа 31
Объединение модулей 71
Объединенный модуль 95
Объект 177, 180
Объектный модуль 94
Оперативная память 17
Оперативный режим 76
Операционная система 22
Опережающая подкачка 127
Очередь 281, 287
— ведущая 84
— готовых процессов 77
— заблокированных процессов 77
— реверсивная 288
— с обратной связью 85
— фоновая 84
Пакетный режим 73—74
Память вспомогательная 17
— оперативная 17
Перекрытие программ 99—102
Перемести мы й модуль 95
Периферийная система ввода-вывода
158-159
Подкачка по запросу 127
Поле записи 150
Пользователь 23
Попеременная загрузка 103—105
Порт 58
— вводной 59
— выводной 59
Поручитель 162
Почтовый ящик 57
----многовходовый 58
----многовыходовый 58
Почтового ящика гнездо 57
Правило вытеснения 132—136, 141—
143
----BIFO 134
----FIFO 133
----LRU 134
Прерывание 18
Привязка 92, 98
Признак 106
Прикладная программа 22
Приоритет 77
— внешний 78
Программа 38
— канала 156
Программное оборудование 16, 19
Пропускная способность 247
Пространство состояний 38
Процедура 35
Процесс 35, 37
Процесс-отец 42
Процесс-сын 42
Процесса дескриптор 40
Процессор 17, 38
Сборка мусора 286
Свободный пул 151
— список 284
Связка 283
Связный список 283—286
----двусторонний 283
----односторонний 283
Сегмент 105
— связей 117
Сегментация 105—108
Семафор 52—56
— двоичный 53
Сеть Петри 290—294
Синтетическая программа 252
Система ввода-вывода 153, 156
— «Венера» 270—278
— расщепления 129
— с прямой связью 74
----разделением времени 75—76
— управления базой данных 155—156,
168—169
----каналами ввода-вывода 157
----файлами 150—164, 169—172
----базисная 155, 159—162
---- логическая 155, 162—164
— ATLAS 140
— MULTICS 278
— SUE 257—270
— THE 210—212, 278
Слово 17
Смесь команд 250
Смещение 105
Сопрограммы 47
Состояние 38
Список 281—286
— возможностей 185
— многосвязный 284
— связный 283—286
— управления доступом 185
— циклический 284
Справочник 152, 289
— главный 163, 169—170
— поручителя 163, 169
Средство 260—263
Статическое установление связей 116—
117
Статус защиты 182—184
Стек 281, 287
Стержень 41, 264—266
Стержневая программа 250
Страничная организация памяти 109—
111
Страничный барабан 125—126
Стратегия вытеснения страниц ПО
— подкачек ПО, 131—132
— распределения памяти 74
Структура данных 235, 281
Структурное программирование 233—
236
— проектирование 205
Субъект 180
Супервизор 28—29
Схема программ 290—298
Счетчик ссылок 285—286
Таблица 288—289
— индексов 166
— сегментов 106, 115
— страниц 109, 115
Терминальная система ввода-вывода
158
Том 153
Транслятор 21
Тупик 64
.Уплотнение 130—131, 282
Установление связей динамическое
117—120
---- статическое 116—117
Устройство ввода-вывода, 17, 26—28
Файл 21, 150
— инвертированный 166
Файла дескриптор 155, 159, 160
Фрагментация памяти 98, 111—113
----внешняя 111
---- внутренняя 111
Функция действия 38
— именующая 92, 99
— памяти 92, 98—100
— потерь 79
— содержимого 92
Хеширование 288
Центральный процессор 17
Циклический список 284
Частичный ключ 165
Эгоистический круговорот 84
Эталонная программа 251
Ядро 22, 216, 259
Язык программирования 227—231
ОГЛАВЛЕНИЕ
Предисловие редакторов перевода ..................................... 5
Предисловие авторов ... . ........................................... 6
Благодарности . . . 4 ...................................... 9
Замечания для преподавателя.......................................... И
Часть I. Принципы
Глава 1. Операционные системы. Функции и основные понятия......... 16
1.1. Введение................................................. 16
1.2. Операционные системы..................................... 22
1.3. Распределение ресурсов................................... 24
1.4. Супервизор............................................... 28
1.5. Заключение............................................... 32
Задания.................................................... 33
Глава 2. Процессы................................................... 35
2.1. Введение.................................................. 35
2.2. Определение процесса...................................... 37
2.3. Реализация процессов...................................... 40
2.4. Общение между процессами ................................. 43
2.5. Синхронизация с помощью элементарных приемов нижнего уров-
ня............................................................. 48
2.6. Элементарные приемы синхронизации на верхнем уровне ... 56
2.7. Тупики..................................................... 64
Задания.................................................... 68
Глава 3. Распределение времени процессора........................... 72
3.1. Введение................................................... 72
3.2. Мультипрограммирование..................................... 74
3.3. Методы планирования в мультипрограммных системах........... 77
3.4. Многоуровневое планирование................................ 86
3.5. Заключительные замечания................................... 89
Задания ................................................... 89
Глава 4. Управление памятью......................................... 92
4.1. Функции для управления памятью............................. 92
4.2. Способы объединения модулей................................ 95
4.3. Распределение памяти....................................... 97
4.4. Перекрытие программ в памяти............................... 99
4.5. Попеременная загрузка заданий............................. 102
4.6. Сегментация............................................... 105
4.7. Страничная организация памяти............................. 108
4.8. Сегментация в сочетании со страничной организацией памяти . . 113
4.9. Установление внешних связей при странично-сегментном методе 116
Задания....................................................... 120
Глава 5. Виртуальная память........................................... 122
5.1. Введение.................................................... 122
5.2. Аппаратные средства для виртуальной памяти......... 123
5.3. Стратегии распределения ресурсов при сегментации и странич-
ной организации................................................. 126
5.4. Анализ типов страничной организации.......................... 136
5.5. Заключительные замечания..................................... 145
Задания....................................................... 145
Часть II. Технология
Глава 6. Ввод-вывод и файлы . * 150
6.1. Введение.................................................. 150
6.2. Система ввода-вывода...................................... 156
6.3. Базисная система управления файлами....................... 159
6.4. Логическая система управления файлами.................... 162
6.5. Методы доступа............................................ 165
6.6. Системы управления базой данных........................... 168
6.7. Пример простой системы управления файлами................. 169
6.8. Заключение................................................ 172
Задания.................................................... 173
Глава 7. Защита. . . *............................................. 176
7.1. Введение.................................................. 176
7.2. Домены и возможности . ................................... 179
7.3. Описание статуса защиты................................... 182
7.4. Реализация защиты......................................... 184
7.5. Передача возможности и формат........................... 187
7.6. Безопасность.............................................. 191
7.7. Заключение......................s......................... 196
Задания . . . ............................................. 197
Глава 8, Проектирование............................................ 200
8.1. Введение.................................................. 200
8.2. Методология проектирования................................ 201
8.3. Подход к проектированию................................... 216
8.4. Руководство проектом...................................... 219
8.5. Заключительные замечания.................................. 223
Задания............................................... • • 224
Глава 9. Реализация................................................ 226
9.1. Введение.................................................. 226
9.2. Выбор языка программирования.............................. 227
9.3. Техника программирования.................................. 231
9.4. Проверка программ......................................... 236
9.5. Оценка эффективности...................................... 243
9.6. Заключение............................................... 254
Задания.............................................. • 255
Глава 10, Примеры систем.......................................... 257
10.1. Введение................................................ 257
10.2. Система SUE............................................. 259
10.3. Операционная система «Венера»........................... 270
10.4. Другие системы.......................................... 278
Задания................................................... 279
Приложение I. Структуры данных.................................... 281
1.1. Определения понятий...................................... 281
1.2. Последовательное размещение списков...................... 282
1.3. Связные списки........................................... 283
1.4. Управление связными списками........................... 284
1.5. Стеки.................................................... 287
1.6. Очереди.................................................. 287
1.7. Реверсивные очереди...................................... 288
1.8. Таблицы................................................. 288
Приложение II. Вычислительные структуры........................... 290
II. 1. Введение............................................... 290
II.2. Сети Петри.............................................. 290
II.3. Вычислительные схемы.................................... 294
II.4. Модель для проблемы тупика............................. 299
II.5. Заключение............................................. 302
Приложение III. «Игрушечная» операционная система................. 303
II 1.1. Введение................................................ 303
II 1.2. Моделируемая аппаратура................................. 304
II 1.3. «Игрушечная» операционная система....................... 306
II 1.4. Заключение.............................................. 307
Список литературы ... .......................................... 309
Предметный указатель ..........................•.................. 331
Д. Цикритзис, Ф. Бернстайн
ОПЕРАЦИОННЫЕ СИСТЕМЫ
Редактор Л. Н. Бабынина Художник А. Д. Смеляков Художественный редактор
В. И. Шаповалов Технический редактор Н. Б. Панфилова Корректор Е. Г. Литвак
Сдано в набор 4/П 1977 г. Подписано к печати 20/V 1977 г. Бумага кн. журн.
60х90/1в = 10,50 бум. л. 2 1,00 усл. печ. л. Уч.-изд. л. 21,88. Изд. № 1/8943.
Цена 1 р. 80 к. Заказ № 1250
ИЗДАТЕЛЬСТВО «МИР» Москва, 1-й Рижский пер., 2
Ордена Октябрьской Революции и ордена Трудового Красного Знамени Первая Образ-
цовая типография имени А. А. Жданова Союзполиграфпрома при Государственном коми-
тете Совета Министров СССР по делам издательств, полиграфии и книжной торговли.
Москва, М-54, Валовая, 28