Файл: А. В. Гордеев А. Ю. Молчанов системное программное обеспечение электронный вариант книги издательства Питер СанктПетербург Челябинск юургу каф. Автоматика и управление 2002 2 Предисловие Настоящий учебник.pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 12.01.2024
Просмотров: 1010
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
73
да/вывода, работавший с дисковым накопителем. Однако в любом случае значение приоритета не может достигнуть 16.
В операционной системе OS/2 схема динамической приоритетной диспетчери- зации несколько иная, хотя и похожа на рассмотренную
1
. В OS/2 имеются четыре класса задач. И для каждого класса задач имеется своя группа приоритетов с ин- тервалом значений от 0 до 31. Итого, 128 различных уровней и, соответственно,
128 возможных очерёдей готовых к выполнению задач (тредов, потоков).
Класс задач, имеющих самые высокие значения приоритета, называется кри-
тическим (time critical). Этот класс предназначается для задач, которые мы в оби- ходе называем задачами реального времени, то есть для них должен быть обяза- тельно предоставлен определенный минимум процессорного времени. Наиболее часто встречающимися задачами, которые относят к этому классу, являются задачи коммуникаций (например, задача управления последовательным портом, прини- мающим биты с коммутируемой линии, к которой подключен модем, или задачи управления сетевым оборудованием). Если такие задачи не получат управление в нужный момент времени, то сеанс связи может прерваться.
Следующий класс задач имеет название приоритетного. Поскольку к этому классу относят задачи, которые выполняют по отношению к остальным задачам роль сервера (о модели клиент–сервер, по которой строятся современные ОС с микроядерной архитектурой, см. в разделе «Микроядерные операционные систе- мы», глава 5), то его ещё иногда называют серверным. Приоритет таких задач дол- жен быть выше, это будет гарантировать, что запрос на некоторую функцию со стороны обычных задач выполнится сразу, а не будет дожидаться, пока до него дойдет очередь на фоне других пользовательских приложений.
Большинство задач относят к обычному классу, его ещё называют регулярным
или стандартным
2
. По умолчанию система программирования порождает задачу,
относящуюся именно к этому классу. Наконец, существует ещё класс фоновых за-
1
Как известно, одно время компания Microsoft принимала активное участие в разработке OS/2 совместно с IBM.
Поэтому после прекращения совместных работ над этой операционной системой и начале нового проекта многие решения из OS/2 были унаследованы в варианте OS/2 ver. 3.0, названной впоследствии Windows NT.
2
Regular.
74
дач, называемый в OS/2 остаточным. Программы этого класса получают про- цессорное время только тогда, когда нет задач из других классов, которым сейчас нужен процессор. В качестве примера такой задачи можно привести программу проверки электронной почты.
Внутри каждого из вышеописанных классов задачи, имеющие одинаковый уровень приоритета, выполняются в соответствии с дисциплиной round-robin. Пе- реход от одного треда к другому происходит либо по окончании отпущенного ему кванта времени, либо по системному прерыванию, передающему управление за- даче с более высоким приоритетом (таким образом, система вытесняет задачи с бо- лее низким приоритетом для выполнения задач с более высоким приоритетом и может обеспечить быструю реакцию на важные события).
OS/2 самостоятельно изменяет приоритет выполняющихся программ незави- симо от уровня, установленного самим приложением. Этот механизм называется
повышением приоритета
1
. Операционная система изменяет приоритет задачи в следующих трех случаях [96]:
♦ Увеличение приоритета активной задачи (foreground boost). Приоритет зада- чи автоматически увеличивается, когда она становится активной. Это снижает вре- мя реакции активного приложения на действия пользователя по сравнению с фоно- выми программами.
♦ Увеличение приоритета ввода/вывода (input/output boost). По завершении операции ввода/вывода задача получает самый высокий уровень приоритета её
класса. Таким образом обеспечивается завершение всех незаконченных операций ввода/вывода.
♦ Увеличение приоритета «забытых» задач (starvation boost). Если задача не получает управление в течение достаточно долгого времени (этот промежуток вре- мени задает оператор MAXWAIT в файле CONFIG.SYS
2
), диспетчер задач OS/2
временно присваивает ей уровень приоритета, не превышающий критический. В
результате переключение на такую «забытую» программу происходит быстрее.
1
Priority boost
2
Строка MAXWAIT=l означает, что приоритет задачи при переключении на неё будет поднят до максимального не позже чем через одну секунду.
75
После выполнения приложения в течение одного кванта времени его приоритет вновь снижается до остаточного. В сильно загруженных системах этот механизм позволяет программам с остаточным приоритетом работать хотя бы в краткие ин- тервалы времени. В противном случае они вообще никогда бы не получили управ- ление.
Если нам нет необходимости использовать метод динамического изменения приоритета, то с помощью оператора PRIORITY = ABSOLUTE в файле CON-
FIG.SYS можно ввести дисциплину абсолютных приоритетов; по умолчанию опе- ратор PRIORITY имеет значение DYNAMIC.
Память и отображения, виртуальное адресное пространство
Если не принимать во внимание программирование на машинном языке (эта технология практически не используется уже очень давно), то можно сказать, что программист обращается к памяти с помощью некоторого набора логических имен,
которые чаще всего являются символьными, а не числовыми и для которого отсут- ствует отношение порядка. Другими словами, в общем случае множество перемен- ных неупорядочено, хотя отдельные переменные и могут иметь частичную упоря- доченность (например, элементы массива). Имена переменных и входных точек
программных модулей составляют пространство имен.
С другой стороны, существует понятие физической оперативной памяти, соб- ственно с которой и работает процессор, извлекая из неё команды и данные и по- мещая в неё результаты вычислений. Физическая память представляет собой упо- рядоченное множество ячеек, и все они пронумерованы, то есть к каждой из них можно обратиться, указав её порядковый номер (адрес). Количество ячеек физиче- ской памяти ограничено и фиксировано.
Системное программное обеспечение должно связать каждое указанное поль- зователем имя с физической ячейкой памяти, то есть осуществить отображение пространства имён на физическую память компьютера. В общем случае это ото- бражение осуществляется в два этапа (рис.2.5): сначала системой программи- рования, а затем операционной системой (с помощью специальных программных
76
модулей управления памятью и использования соответствующих аппаратных средств вычислительной системы). Между этими этапами обращения к памяти имеют форму виртуального или логического адреса. При этом можно сказать, что множество всех допустимых значений виртуального адреса для некоторой про- граммы определяет её виртуальное адресное пространство или виртуальную па- мять. Виртуальное адресное пространство программы прежде всего зависит от ар- хитектуры процессора и от системы программирования и практически не зависит от объёма реальной физической памяти, установленной в компьютер. Можно ещё
сказать, что адреса команд и переменных в готовой машинной программе, под- готовленной к выполнению системой программирования, как раз и являются вир- туальными адресами.
Рис. 2.5. Память и отображения
Виртуальное адресное пространство
Виртуальный адрес
Физическая память компьютера
Ячейка оперативной памяти
(физический адрес)
Логическое (символьное) имя
Пространство имён программы
Система программирования
Операционная система
77
Как мы знаем, система программирования осуществляет трансляцию и компо- новку программы, используя библиотечные программные модули (подробно об этом см. часть 2 настоящего учебника). В результате работы системы програм- мирования полученные виртуальные адреса могут иметь как двоичную форму, так и символьно-двоичную, то есть некоторые программные модули (их, как правило,
большинство) и их переменные получают какие-то числовые значения, а те моду- ли, адреса для которых не могут быть сейчас определены, имеют по-прежнему символьную форму и окончательная привязка их к физическим ячейкам будет осуществлена на этапе загрузки программы в память перед её непосредственным выполнением.
Одним из частных случаев отображения пространства имен на физическую па- мять является тождественность виртуального адресного пространства физической памяти. При этом нет необходимости осуществлять второе отображение. В данном случае говорят, что система программирования генерирует абсолютную двоичную
программу; в этой программе все двоичные адреса таковы, что программа может исполняться только в том случае, если её виртуальные адреса будут точно соответ- ствовать физическим. Часть программных модулей любой операционной системы обязательно должна быть абсолютными двоичными программами. Эти программы размещаются по фиксированным адресам и с их помощью уже можно впоследст- вии реализовывать размещение остальных программ, подготовленных системой программирования таким образом, что они могут работать на различных физиче- ских адресах (то есть на тех адресах, на которые их разместит операционная систе- ма).
Другим частным случаем этой общей схемы трансляции адресного простран- ства является тождественность виртуального адресного пространства исходному пространству имен. Здесь уже отображение выполняется самой ОС, которая во вре- мя исполнения использует таблицу символьных имен. Такая схема отображения используется чрезвычайно редко, так как отображение имен на адреса необходимо выполнять для каждого вхождения имени (каждого нового имени) и особенно мно- го времени тратится на квалификацию имен. Данную схему можно было встретить
78
в интерпретаторах, в которых стадии трансляции и исполнения практически нераз- личимы. Это характерно для простейших компьютерных систем, в которых вместо операционной системы использовался встроенный интерпретатор (например, Ba- sic).
Возможны и промежуточные варианты. В простейшем случае транслятор-ком- пилятор генерирует относительные адреса, которые, по сути, являются виртуаль- ными адресами с последующей настройкой программы на один из непрерывных разделов. Второе отображение осуществляется перемещающим загрузчиком. После загрузки программы виртуальный адрес теряется, и доступ выполняется не- посредственно к физическим ячейкам. Более эффективное решение достигается в том случае, когда транслятор вырабатывает в качестве виртуального адреса от- носительный адрес и информацию о начальном адресе, а процессор, используя подготавливаемую операционной системой адресную информацию, выполняет второе отображение не один раз (при загрузке программы), а при каждом обра- щении к памяти.
Термин виртуальная память фактически относится к системам, которые со- храняют виртуальные адреса во время исполнения. Так как второе отображение осуществляется в процессе исполнения задачи, то адреса физических ячеек могут изменяться. При правильном применении такие изменения могут улучшить ис- пользование памяти, избавив программиста от деталей управления ею, и даже уве- личить надёжность вычислений.
Если рассматривать общую схему двухэтапного отображения адресов, то с по- зиции соотношения объёмов упомянутых адресных пространств можно отметить наличие следующих трех ситуаций:
♦ объём виртуального адресного пространства программы V
v меньше объёма физической памяти V
p
;
♦ V
v
= V
p
;
♦ V
v
> V
p
Первая ситуация, при которой V
v
< V
p
, ныне практически не встречается, но тем не менее это реальное соотношение. Скажем, не так давно 16-разрядные мини-
79
ЭВМ имели систему команд, в которых пользователи-программисты могли адресо- вать до 2 16
=64K адресов (обычно в качестве адресуемой единицы выступала ячейка памяти размером с байт). А физически старшие модели этих мини-ЭВМ могли иметь объём оперативной памяти в несколько мегабайт. Обращение к памяти столь большого объёма осуществлялось с помощью специальных регистров, содержимое которых складывалось с адресом операнда (или команды), извлекаемым и/или оп- ределяемым из поля операнда (или из указателя команды). Соответствующие зна- чения в эти специальные регистры, выступающие как базовое смещение в памяти,
заносила операционная система. Для одной задачи в регистр заносилось одно зна- чение, а для второй (третьей, четвертой и т. д.) задачи, размещаемой одновременно с первой, но в другой области памяти, заносилось, соответственно, другое значе- ние. Вся физическая память, таким образом, разбивалась на разделы объёмом по 64
Кбайт, и на каждый такой раздел осуществлялось отображение своего виртуально- го адресного пространства.
Ситуация, когда V
v
= V
p встречается очень часто, особенно характерна она была для недорогих вычислительных комплексов. Для этого случая имеется боль- шое количество методов распределения оперативной памяти.
Наконец, в наше время мы уже достигли того, что ситуация V
v
> V
p встречает- ся даже в ПК, то есть в самых распространенных и недорогих компьютерах. Теперь это самая распространенная ситуация и для неё имеется несколько методов рас- пределения памяти, отличающихся как сложностью, так и эффективностью.
Простое непрерывное распределение и распределение с перекрытием
(оверлейные структуры)
Простое непрерывное распределение – это самая простая схема, согласно ко- торой вся память условно может быть разделена на три части:
♦ область, занимаемая операционной системой;
♦ область, в которой размещается исполняемая задача;
♦ незанятая ничем (свободная) область памяти.
Изначально являясь самой первой схемой, она продолжает и сегодня быть до- статочно распространенной. Эта схема предполагает, что ОС не поддерживает
80
мультипрограммирование, поэтому не возникает проблемы распределения памяти между несколькими задачами. Программные модули, необходимые для всех про- грамм, располагаются в области самой ОС, а вся оставшаяся память может быть предоставлена задаче. Эта область памяти при этом получается непрерывной, что облегчает работу системы программирования. Поскольку в различных однотипных вычислительных комплексах может быть разный состав внешних устройств (и, со- ответственно, они содержат различное количество драйверов), для системных нужд могут быть отведены отличающиеся объёмы оперативной памяти, и получается,
что можно не привязывать жестко виртуальные адреса программы к физическому адресному пространству. Эта привязка осуществляется на этапе загрузки задачи в память.
Чтобы для задач отвести как можно больший объём памяти, операционная система строится таким образом, что постоянно в оперативной памяти располагает- ся только самая нужная её часть. Эту часть ОС стали называть ядром. Остальные модули ОС могут быть обычными диск-резидентными (или транзитными), то есть загружаться в оперативную память только по необходимости, и после своего вы- полнения вновь освобождать память.
Такая схема распределения влечет за собой два вида потерь вычислительных ресурсов – потеря процессорного времени, потому что процессор простаивает, пока задача ожидает завершения операций ввода/вывода, и потеря самой оперативной памяти, потому что далеко не каждая программа использует всю память, а режим работы в этом случае однопрограммный. Однако это очень недорогая реализация и можно отказаться от многих функций операционной системы. В частности, такая сложная проблема, как защита памяти, здесь вообще не стоит.
Мы не будем рассматривать все различные варианты простого непрерывного распределения памяти, которых было очень и очень много, а ограничимся схемой распределения памяти для MS-DOS (см. раздел «Распределение оперативной памя- ти в MS-DOS», глава 2).
Если есть необходимость создать программу, логическое (и виртуальное) ад- ресное пространство которой должно быть больше, чем свободная область памяти,
81
или даже больше, чем весь возможный объём оперативной памяти, то используется распределение с перекрытием (так называемые оверлейные структуры
1
). Этот ме- тод распределения предполагает, что вся программа может быть разбита на части –
сегменты. Каждая оверлейная программа имеет одну главную часть (main) и не- сколько сегментов (segment), причем в памяти машины одновременно могут нахо- диться только её главная часть и один или несколько не перекрывающихся сегмен- тов.
Пока в оперативной памяти располагаются выполняющиеся сегменты, осталь- ные находятся во внешней памяти. После того как текущий (выполняющийся) сег- мент завершит свое выполнение, возможны два варианта. Либо он сам (если дан- ный сегмент не нужно сохранить во внешней памяти в его текущем состоянии) об- ращается к ОС с указанием, какой сегмент должен быть загружен в память сле- дующим. Либо он возвращает управление главному сегменту задачи (в модуль main), и уже тот обращается к ОС с указанием, какой сегмент сохранить (если это нужно), а какой сегмент загрузить в оперативную память, и вновь отдает управле- ние одному из сегментов, располагающихся в памяти. Простейшие схемы сегмен- тирования предполагают, что в памяти в каждый конкретный момент времени мо- жет располагаться только один сегмент (вместе с модулем main). Более сложные схемы, используемые в больших вычислительных системах, позволяют распола- гать по несколько сегментов. В некоторых вычислительных комплексах могли су- ществовать отдельно сегменты кода и сегменты данных. Сегменты кода, как пра- вило, не претерпевают изменений в процессе своего исполнения, поэтому при за- грузке нового сегмента кода на место отработавшего последний можно не сохра- нять во внешней памяти, в отличие от сегментов данных, которые сохранять необ- ходимо.
Первоначально программисты сами должны были включать в тексты своих программ соответствующие обращения к ОС (их называют вызовами) и тщательно планировать, какие сегменты могут находиться в оперативной памяти одновре- менно, чтобы их адресные пространства не пересекались. Однако с некоторых пор
1
От overlay – перекрытие, расположение поверх чего-то.
82
эти вызовы система программирования стала подставлять в код программы сама,
автоматически, если в том возникает необходимость. Так, в известной и популяр- ной системе программирования Turbo Pascal, начиная с третьей версии, програм- мист просто указывал, что данный модуль является оверлейным. И при обращении к нему из основной программы модуль загружался в память и ему передавалось управление. Все адреса определялись системой программирования автоматически,
обращения к DOS для загрузки оверлеев тоже генерировались системой Turbo Pas- cal.
Распределение статическими и динамическими разделами
Для организации мультипрограммного режима необходимо обеспечить одно- временное расположение в оперативной памяти нескольких задач (целиком или их частями). Самая простая схема распределения памяти между несколькими задача- ми предполагает, что память, незанятая ядром ОС, может быть разбита на несколь- ко непрерывных частей (зон, разделов
1
). Разделы характеризуются именем, типом,
границами (как правило, указываются начало раздела и его длина).
Разбиение памяти на несколько непрерывных разделов может быть фиксиро- ванным (статическим), либо динамическим (то есть процесс выделения нового раз- дела памяти происходит непосредственно при появлении новой задачи).
Вначале мы кратко рассмотрим статическое распределение памяти на не- сколько разделов.
1 2 3 4 5 6 7 8 9 10 ... 37