МИНИСТЕРСТВО ОБРАЗОВАНИЯ РФ Восточно-Сибирский государственный технологический университет
Степанов Б.М.
Организация в...
11 downloads
213 Views
243KB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
МИНИСТЕРСТВО ОБРАЗОВАНИЯ РФ Восточно-Сибирский государственный технологический университет
Степанов Б.М.
Организация вычислительных процессов Конспект лекций по дисциплине «Системы реального времени» для студентов специальности 220400 «Программное обеспечение ВТ и АС»
Издательство ВСГТУ Улан-Удэ, 2001
УДК 681.142 Организация вычислительных процессов: конспект лекций/ Сост. Степанов Б.М. – УланУдэ, Изд-во ВСГТУ, 2001.- 41 с. Конспект лекций предназначен для студентов специальности 220400 и 351500 и содержит теоретический материал по дисциплине «Системы реального времени», в котором изложены основные понятия вычислительных процессов, диспетчеров процессов, состояний и алгоритмы управления реальными процессами.
Рецензент: Найханова Л.В., к.т.н., доц. ВСГТУ.
Печатается по решению редакционно-издательского совета ВСГТУ ВСГТУ, 2001 г. Степанов Б.М.
Оглавление
Введение Лекция 1. Понятие и внутреннее представление процесса Лекция 2. Управление процессами Лекция 3. Построение простейшего диспетчера Лекция 4. Процедура обработки прерываний Лекция 5. Диспетчер с относительным круговым приоритетом Лекция 6. Управление процессами с тремя состояниями Лекция 7. Создание и уничтожение процессов Лекция 8. Управление процессами с учётом времени Список рекомендуемой литературы
Введение
В работе даются понятия вычислительных процессов, их состояний процессов, переходов из состояния в состояние, переключения контекста, дескрипторов процессов, диспетчеров. Рассматриваются основные типы многозадачности, основные виды дисциплин обслуживания и алгоритмы работы диспетчеров процессов. Эти понятия являются базовыми при проектировании многозадачных операционных систем. Изучение данной дисциплины входит в блок дисциплин по системному программированию.
Лекция 1. Понятие и внутреннее представление процесса Вычислительный процесс – последовательность выполнения команд программы. {P1, P2, P3, . . . . . , Pn} множество процессов, составленных в соответствии с множеством {D1, D2, D3, . . . . , Dn} дескрипторов. Каждый процесс определим как дескриптор и программу. Dk PROGk В каждый момент времени работы многозадачной операционной системы может быть несколько процессов. Список процессов строится из дескрипторов процессов. type связь = ^дескриптор; {связь есть ссылка на дескриптор} связь1 = ^дискриптор1; дескриптор = record следующий: связь; адрес программы: связь1; end Каждый дескриптор процессора состоит из двух полей: D следующий адрес программы
Введём переменные для работы с таким списком: var начало,текпроц : связь; текпроц.
начало PROG
PROG
PROG
PROG
Текущий процесс (текпроц) – указатель на выполняемый в данный момент процесс. Начало- указатель на начало очереди дескрипторов. Определение процессов В специализированных системах, которые называют ещё встроенными системами, предназначенных для целей управления, обычно совокупность решаемых задач известна заранее, и все программы , которые должна выполнять система, включаются в неё при создании. В таких системах множество процессов (т.е. множество программ), которыми необходимо управлять, фиксируется при создании системы. Это множество не изменяется в процессе работы системы. В системах общего назначения список процессов заранее не известен. Он создаётся в период работы и может видоизменяться. Для этой цели предоставляются специальные средства. Например, процедуры “создать процесс”, “уничтожить процесс”. Эти процедуры создают дескрипторы процесса и включают (исключают) в список (из списка) процессов.
Лекция 2. Управление процессами Обычно управление процессами, т.е. выбор процесса и активизацию осуществляет системная программа «диспетчер». Для связи пользователя с этой программой создаются специальные процедуры, которые называются “примитивами” диспетчера. Для запуска подпрограммы традиционно используется 2 средства : оператор перехода goto и обращение к подпрограмме. Если обращение к подпрограмме выполняется с помощью прерывания, то такая подпрограмма называется “примитивом”. Поскольку при таком обращении может происходить переключение режима (пользователя, системного процесса, супервизора). Переключение процессов Допустим, выполняется некоторый процесс Р. В некоторый момент времени он обращается к диспетчеру с помощью примитива, сообщая, что он закончил свою работу. В этом случае должно производиться переключение контекста: «выполняемый процесс» – «диспетчер». Диспетчер должен выбрать следующий процесс, который он активизирует и осуществляет второе переключение контекста, т.е. запомнить контекст диспетчера и восстановить контекст нового процесса. Стек является наилучшим вариантом реализации хранения контекста. При вызове вложенных подпрограмм осуществляется запись контекста вызываемой подпрограммы в стек, а при возврате происходит восстановление контекста (обязательно в обратном порядке по отношению к запоминанию). Если используется произвольный порядок, то контекст может оказаться недоступным (не находится в вершине стека). Процессы отличаются от подпрограмм тем, что они могут активизироваться, в общем случае, в произвольном порядке. Поэтому вместо того, чтобы использовать один стек для сохранения всех контекстов используют отдельный для каждого процесса. Если ориентироваться на систему со многими стеками для каждого процесса, то дескриптор процесса должен включать указатель на стек процесса. type
связь = ^дескриптор; связь1 = ^процесс; связь2 = ^стек; дескриптор = record; следующий: связь; адрес программы : связь1; адрес стека: связь2;
end Теперь имеем 3 поля :
следующий адрес программы адрес стека
При входе в диспетчер переключение контекста необходимо, но при выходе из диспетчера контекст можно было бы не сохранять, считая, что диспетчер всегда заканчивает работу путём задания контекста нового процесса. Однако мы примем общий механизм переключения контекста, который применим для существующих переключений.
Допустим, что такое общее переключение контекстов задаётся с помощью процедуры «переключить». d1 – ссылка на дескриптор выполняемого процесса, d2 – ссылка на дескриптор процесса, который нужно активизировать. Переключить (d1, d2); (где d1, d2 –параметры процедуры “переключить”) Эта процедура выполняет: 1) сохранение контекста выполняемого процесса в его стеке, 2) восстановление контекста активизируемого процесса из его стека. Можно считать, что в случае прерывания процедура “переключить” выполняется аппаратно. Типы диспетчера При построении диспетчера обычно учитывают следующие характеристики: 1) Способ выбора очередного процесса из списка для активизации Правила: а) в порядке очереди, б) с фиксированным относительным процессом, в) с круговым относительным процессом, г) с абсолютным процессом. 2) Учёт времени выполнения процесса а) процессам выдаются одинаковые кванты времени, б) процессам выдаются различные кванты времени. Лекция 3. Построение простейшего диспетчера Допустим, что число процессов, которыми должен управлять диспетчер, фиксируется при начальном запуске системы и дальше остаётся неизменным в процессе работы. В начале рассмотрим диспетчер, выполняющий выбор очередного процесса в соответствии с принципом относительного фиксированного приоритета. Этот принцип предполагает, что прерывания, возникающие при выполнении некоторого процесса, не должны приводить к его остановке пока он не завершится. Допускается только приостановка процесса на время обработки прерываний. Структура дескриптора Состояния процесса В простейшем случае каждый процесс может находиться в двух состояниях: 1) состояние готовности, 2) состояние ожидания. Диспетчер, просматривая список процессов, может запускать только те процессы, которые находятся в состоянии готовности. Таким образом, чтобы запустить некоторый процесс, необходимо вначале перевести его в состояние готовности, а затем активизировать его. Изменение состояния процесса обычно выполняет пользователь с помощью специального примитива диспетчера. Такие примитивы пользователь может включать в программу. Пусть в нашем диспетчере используется два примитива: – готов(к), где к – номер процесса, состояние которого нужно изменить, – ждать – процедура, которая переводит процесс в состояние ожидания.
ждать ожидание состояние = false
готовность
готов
состояние = true
Чтобы в системе хранить состояние каждого процесса и иметь возможность анализировать его, добавим к дескриптору ёще одно поле – “состояние”. В результате получим следующий тип дескриптора: следующий адрес процесса адрес стека состояние
type связь = ^дескриптор; связь1 = ^процесс; связь2 = ^стек; дескриптор = record следующий : связь; адрес процесса : связь1; адрес стека : связь2; состояние : boolean; end;
Поле “состояние” может принимать значение – true (состояние готовности), – false (состояние ожидания). Каждый процесс, будучи запущенным, может обратиться к диспетчеру с помощью примитивов. В существующий момент времени процесс может обрабатывать сигнал, позволяющий переводить его состояние ожидания. Каждый процесс заканчивается процедурой “ждать”. Процедура “ждать” применима только к выполняемому процессу и должна производить выбор следующего процесса. Действия, выполняемые диспетчером 1. Действия диспетчера при выполнении процедуры “готов” Допустим, что диспетчер работает со списком дескрипторов, который представляет собой цепной список. Последний элемент этого списка в поле ”следующий” имеет nil (пустой). Первый элемент цепного списка определяется специальной переменной – начало (эта переменная хранит ссылку на первый элемент). Для работы диспетчер будет использовать ещё одну переменную – текущийпроцесс. Значением этой переменной является ссылка на дескриптор выполняемого в данный момент времени процесса. Допустим, что выполнение процедур обращения к диспетчеру начинается с системного прерывания. Таким образом, при обращении
1) автоматически выполняется запоминание контекста в системном стеке; 2) восстанавливается контекст диспетчера; 3) находится процесс с номером К в списке процессов; 4) изменяется состояние процесса, т.е. присваивается новое значение полю дескриптора (true); 5) восстанавливается контекст процесса, выдавшего запрос диспетчеру; 2. Действия диспетчера при выполнении процедуры “ждать” 1) автоматически выполняется сохранение контекста процесса, обратившегося к диспетчеру, в системный стек и восстановление контекста диспетчера; 2) активный процесс, ссылка на который является значением “текущий процесс”, переводится в состояние отрицания: текущийпроцесс^.адресстека := false; 3) контекст процесса, обратившегося к диспетчеру, из системного стека переносится в стек процесс. Адрес стека определяется следующим образом: текущийпроцесс^.адресстека; 4) выполняется выбор следующего процесса, который можно запустить. Допустим, что это делает процедура “Выбор”. Эта процедура просматривает список процессов, начиная всегда с первого дескриптора в списке, и выбирает всегда первый процесс, находящийся в состоянии “готов”. При этом она ссылку на новый процесс заносит в переменную “текущий процесс”; 5) выполняется загрузка контекста выбранного процесса в системный стек. Адрес стека, откуда выбирается контекст, определяется переменной: текущийпроцесс^.адрес стека; 6) выполняется переключение контекста аналогично команде возврата из процедуры обработки прерывания iret, т.е. из системного стека контекст загружается в память процессора. Лекция 4. Процедура обработки прерываний При работе системы запрос на прерывание может появиться как во время выполнения процесса, так и при выполнении диспетчера. При этом должны выполняться следующие действия: 1) сохранение контекста процесса или диспетчера и осуществление перехода к процедуре обработки прерываний; 2) обработка, в результате которой могут быть, например, прочитаны данные из устройства и переданы в буфер. Программа обработки прерываний может активизировать некоторый процесс, ожидающий сигнала прерываний, с помощью процедуры “готов”; 3) переключение контекста, т.е. восстановление контекста, хранящегося в системном стеке. Набор процедур диспетчера 1. Процедура “готов” Procedure Готов (K:int); Var Р: связь; i : int; Begin P:=начало; i:=1; While i<>K do begin
{K – номер процесса}
P:=P^.следующий; i:=i+1; end; P^.состояние:=true; end; Оператор цикла осуществляет просмотр дескрипторов, пока не будет обнаружен дескриптор, номер которого i равен заданному К. В теле цикла выполняется определение ссылки на следующий элемент и изменение номера дескриптора. После того как процесс найден, ссылка на него является значением переменной Р. Состояние процесса меняется в соответствии с этой переменной. 2. Процедура “ждать” Procedure ждать; begin текущийпроцесс^.состояние:=false; Передать контекст процесса (текущийпроцесс^.адресстека); {осуществляется пересылка контекста из системного стека в стек текущего процесса} Выбрать; {Процедура осуществляет поиск и выбор очередного процесса, который должен выполняться. Ссылку на этот процесс она присваивает переменной текущего процесса} Загрузить контекст процесса (текущий процесс^.адрес стека); {Процедура осуществляет передачу контекста из стека нового (выбранного) процесса в системный стек} Переключить контекст; {Эта процедура действует аналогично команде Iret, передавая контекст из системного стека в память процессора} 3. Процедура “выбрать” Назначение: выделение из списка процессов следующего процесса, который получает в своё распоряжение процессор. Т.к. эта процедура работает в равенстве с принципом фиксированного относительного приоритета, то необходимо предусмотреть следующее: 1) дескрипторы в списке процессов должны быть расположены в порядке убывания приоритетов. 2) просмотр списка должен всегда выполняться, начиная с первого элемента. procedure выбрать; var р: связь; b: boolean; begin p:=начало; b:=true; {p указывает на первый процесс, b –параметр цикла} while b do {цикл просмотра процессов} if p^.состояне then begin текущий процесс :=p; b:= false; end; {если состояние рассматриваемого процесса – “готов”, то ссылка на этот процесс запоминается переменной “текущий процесс” и изменяется значение переменной, определяющей окончание цикла}
else if p^.следующий<>nil then p:=p^.следующий; {если очередной дескриптор не является последним в списке процессов, то переменной р присваивается ссылка на следующий дескриптор} else begin b:=false; Вывести сообщение (“Нет готовых процессов”); {если рассматриваемый дескриптор – последний в списке процессов, то изменяется значение переменной, определяющей выход из цикла и выводится сообщение} end; end; Готовых процессов в списке может не оказаться, если в система ожидает какого-либо внешнего события. В этом случае, вместо сообщения может повторить просмотр списка процессов. Таким образом, диспетчер может зациклиться на просмотре списка процессов. Это зацикливание равносильно режиму ожидания системы. Другой вариант работы системы может состоять в том, что после вывода сообщения при отсутствии готовых процессов оператор с помощью процедуры “готов” активизирует какой-либо процесс, игнорируя работу системы. Лекция 5. Диспетчер с относительным круговым приоритетом Относительный круговой приоритет предусматривает, что дескрипторы процессов упорядочены в соответствии с приоритетами и, что после завершения k-го процесса в списке, просмотр списка для выбора очередного процесса начинается с k+1-го процесса. Кроме того, при достижении последнего элемента списка должен осуществляться переход к началу списка. Для реализации принципа относительного кругового приоритета список процессов должен быть замкнут, т.е. в последнем дескрипторе списка в поле “следующий” должна быть записана ссылка на первый элемент. Такой диспетчер может отличаться от предыдущего только одной процедурой “выбрать”. procedure выбрать1; var p:связь; b:boolean; begin p:=текущийпроцесс; b:=true; while b do if p^.состояние then begin текущий процесс:=p; b:=false; end; else if p^.следующий<>текущий процесс then p:=p^.следующий else вывести сообщение (“Нет готовых процессов”); end;
Процедура “выбрать1” определяет конец просмотра списка процессов по следующему отношению р^.следующий:= текущий процесс В этом случае она выводит сообщение об отсутствии готовых процессов и продолжает просмотр списка процессов, который соответствует состоянию ожидания. Диспетчер с абсолютным приоритетом Принцип абсолютных приоритетов предполагает, что при появлении запроса на прерывание от процесса, приоритет которого выше, чем приоритет выполняющегося процесса, должна произойти передача процесса к процессу с наивысшим приоритетом. При построении диспетчера допустим, что при отсутствии запросов с помощью прерываний диспетчер должен работать в равенстве с принципом относительного приоритета. Кроме того, среди процессов, определённых в системе, могут быть процессы, имеющие одинаковый приоритет. В этом случае, для работы с такими процессами диспетчер также должен использовать относительный приоритет, определённый порядком расположения этих процессов в списке. Таким образом, мы приходим к смешанной дисциплине обслуживания. Чтобы диспетчер мог определить приоритет каждого процесса, его необходимо задать явным образом. Обычно процессу приписывают приоритет в виде целого числа. Для хранения значения приоритета введём в дескриптор процесса ещё одно поле с именем «Приоритет». type
связь = ^дескриптор; связь1 = ^процесс; связь2 = ^стек;
дескриптор = record : связь; адрес процесса : связь; адрес стека : связь; состояние : boolean; приоритет : int; end;
следующий адрес процесса адрес стека состояние приоритет
Работа диспетчера, использующего абсолютный приоритет Диспетчер построен на основе уже описанного, полагая, что пользователь имеет в распоряжении примитивы “готов” и “ждать”. В случае появления прерывания работает программа обработки прерывания. Если она определяет, что причиной прерывания является запрос на активизацию некоторого процесса, то она должна обратиться к диспетчеру для того, чтобы он попытался запустить требуемый процесс. Для запуска с учётом абсолютных приоритетов введём ещё один примитив диспетчера, который назовём “запустить (k)”, где k – номер процесса в списке. Эта процедура должна выполнять следующие действия: 1) найти дескриптор процесса с номером k в списке процессов; 2) изменить состояние найденного процесса на “готов”; 3) сравнить абсолютные приоритеты процесса с номером k и текущего. Если последний больше, то продолжать выполнение текущего. В противном случае необходимо: – заполнить контекст текущего процесса в стеке;
– загрузить контекст процесса k в системный стек; – осуществить переключение контекста; 4) перед переключением контекста необходимо изменить значение указателя текущего процесса. procedure запустить (k : int); var p: связь; i : int; begin p:= начало; i := 1; while i<>k do begin p:=p^.следующий; i:=i+1; end; p^.состояние :=true; if p^.приоритет > текущий процесс^.приоритет then begin передать контекст процесса (текущий процесс^.адрес стека); загрузить контекст процесса (p^.адрес стека); текущий процесс :=р; end; переключить контекст; end. Лекция 6. Управление процессами с тремя состояниями В рассмотренных выше примерах выполняющийся процесс не может приостановить себя, оставшись в состоянии готовности. Процесс, находящийся в состоянии ожидания, может быть переведён в состояние готовности только другим процессом. Рассмотрим ситуацию: Pi – активный процесс. Pi должен активизировать некоторый драйвер Pk. Pk – выполняет порцию вывода данных и активизирует Pi и т. д. Это неудобно, так как к Pk могут обращаться разные процессы, и заранее не известно какой процесс надо будет ему активизировать. Удобна следующая схема работы: Pi переводит в состояние готовности Pk и и переводит себя в состояние ожидания, сохраняя при этом состояние готовности. Таким образом, в списке процессов два готовых процесса Pi и Pk. Допустим, что Pk имеет более высокий приоритет (расположен ближе к началу списка). В этом случае диспетчер выбирает и активизирует Pk. Если Pk закончит работу с помощью команды “Ждать”, которая переведёт Pk в состояние ожидания, то в качестве следующего активного процесса будет выбран Pi. Чтобы реализовать желаемые способы работы введём ещё одно состояние процесса. Для обозначения трёх состояний одной булевской переменной недостаточно, поэтому, кроме переменной “состояние” введём переменную “сигнал”. Var состояние, сигнал : boolean;
ждать состояние = false сигнал = false
состояние = false сигнал = true
ожидание
активность
готов
выбор
состояние = true сигнал = true готовность
Рис.1 Чтобы примитивы – готов, ждать и выбор- можно было использовать для управления процессами с тремя состояниями в них нужно добавить операторы, изменяющие значение поля “сигнал” в дескрипторе. Эти изменения сводятся к добавлению оператора в процедуры «Готов» и «Выбор» и несколько сложнее в процедуре «ждать». Условимся, что если текущий процесс хочет приостановиться с сохранением состояния готовности, то он должен вначале вызвать процедуру «Готов», а затем процедуру «Ждать». Так как переменные, определяющие состояние процесса имеют разные значения, в зависимости от того предшествовала ли выполнению процедуры «Готов» процедура «Ждать», то процедура «Ждать» по этим значениям может определить, нужно ли переводить процесс в состояние ожидания. ждать
состояние = false сигнал = true
готов ждать
состояние = true сигнал = true
Реализация выявления состояния процесса в процедуре «Ждать» 1-й случай: Диспетчер работает с маскированием прерывания.
Текущий процесс^. состояtrue
false Текущий процесс^. сигнал
Рис.2
Изменение в процедуре «Ждать»: If not Текущий процесс^. состояние then Текущий процесс^. сигнал := false; 2-й случай: Допустим, что в процессе работы диспетчера допускается прерывание. Такая ситуация имеет место в системах реального времени. Рассмотрим случай, когда прерывание произошло. Допустим, что в результате прерывания программа обработки прерывания хочет вновь активизировать текущий процесс и устанавливает переменной “состояние” и “сигнал” true. Однако после выхода из программы обработки прерываний оператор Текущий процесс^. сигнал := false сбросит значение сигнал и в результате мы получим запретное состояние процесса. Чтобы это исключить, изменим порядок анализа переменных и присваивания:
Текущий процесс^. сигнал Текущий процесс^. состояfalse
true Текущий процесс^. сигнал
Рис.3 Та же ситуация, но запрещённого состояния не получим.
Лекция 7. Создание и уничтожение процессов В отличие от рассмотренных ранее специальных систем, в системах общего назначения количество процессов в каждый момент времени может изменяться, т.е. могут появляться новые процессы и могут уничтожаться закончившиеся процессы. Создание процессов может выполняться: а) как при обработке шага задания; б) так и пользователем, которому предоставляются специальные примитивы создания и уничтожения процессов. Рассмотрим оба случая: 1) Допустим, что рассматривается однопользовательская операционная система (для персональных компьютеров). В такой системе пользователю обычно предоставляется право создавать процесс, но не предусматривается возможность уничтожения процесса, т.е. все процессы уничтожаются при завершении сеанса работы. 2) Если система многопользовательская (системы с разделением времени), то необходимо предусмотреть примитивы создания и уничтожения процессов. Например, уничтожение должно выполняться по завершению шага задания. 1-й случай: Создание процессов предполагает, что должны быть известны начальный адрес программы и адрес стека программы. Программа должна построить дескриптор для нового создаваемого процесса, заполнить его и включить в список процессов и активизировать новый процесс. При этом необходимо условиться, в какое место списка включить процесс. Условимся, что при круговом способе организации списка новый процесс должен включаться всегда перед текущим. Procedure Создать процесс (новый адрес процесса: процесс; новый адрес стека : адрес); Var r, r1 : связь; Begin r:= текущий процесс; while r^. следующий <>текущий процесс do r:= r^. следующий; {Цикл поиска дескриптора процесса, ссылающегося на текущий процесс} New (r1); {Создание динамической переменной типа дескриптор. Ссылка на него в r1} r1^. следующий := текущий процесс; r1^. Следующий := r1; {Включение нового дескриптора в список процессов перед дескриптором, на который указывает текущий процесс} r1^. адрес процесса := новый адрес процесса; r1^. адрес стека := новый адрес стека; r1^.состояние := false; r1^.сигнал :=true; {Перевод процесса в активное состояние} Передать контекст процесса (текущий процесс^. адрес стека); Текущий процесс := r1; Загрузить контекст процесса (текущий процесс^. адрес стека); Переключить контекст;
End. 2-й случай: Многопользовательская система. Для создания имя процесса можно не указывать, но для уничтожения необходимо указать, какой именно процесс уничтожается. Таким образом, во-первых, следует необходимость именования процессов, во-вторых, так как система многопользовательская, то существует вероятность, что разные пользователи выберут один и тот же процесс. Таким образом, оказывается необходимым двойное именование в системе: а) на уровне пользователя б) на уровне системы На уровне системы не должно быть повторяющихся имён. В качестве системного имени выберем составное имя, состоящее из имени задания и имени процесса, полагая при этом, что все задания имеют разные имена. Если это не так, то необходимо вводить двухуровневую систему имён задания. Каждому составному имени процесса поставим в соответствие ссылку на дескриптор. Появляется необходимость таблицы соответствия, которую можно описать следующим образом: Type ID = array [1..N]of char;
{количество символов в одном имени}
соответствие = record имя задания : ID; имя процесса : ID; внутреннее имя : связь; end; Var Таблица имён процессов : array [ 1..M] of соответствие;
Имя задания
Имя процесса
Внутреннее имя
X1
A
P1
X1
B
P2
X2
B
P3
X2
C
P4
{число имён}
Для работы с таблицами определим 3 процедуры: 1. Занести имя (имя процесса : ID; внутреннее имя: связь). 2. Найти имя (имя процесса : ID; внутреннее имя : связь); {Эта процедура для заданного имени процесса определяет ссылку на его дескриптор}. 3. Исключить имя (имя процесса : ID); {Эта процедура вычёркивает строку в таблице имён процессов}. Procedure Удалить процесс (внешнее имя : ID); Var r, r1: связь; Begin Найти (внешнее имя, r); {Процедура для заданного внешнего имени находит в таблице соответствия внутреннее имя процесса, которое представляет собой ссылку на дескриптор процесса}
r1:=r; While r1^.следующий <> r do r1:= r1^. следующий; {Цикл выполняет поиск в списке процессов дескриптора, который ссылается на удаляемый процесс} r1^. следующий:= r^. следующий; {Операция, исключающая дескриптор удаляемого процесса из списка процессов} Исключить имя (внешнее имя); {процедура исключает из таблицы соответствия внешнее и внутреннее имена удаляемого процесса} If r <> текущий процесс then Переключить контекст else begin Выбрать; {Определяет следующий процесс, готовый к выполнению в списке процессов и ссылку на него присваивает переменной “текущий процесс”} Загрузить контекст (текущий процесс^.адрес стека); Переключить контекст; End. Лекция 8. Управление процессами с учётом времени Учет времени исполнения используется: а) в специальных системах (исполнительных); б) в системах общего назначения. Существует два основных режима: 1) каждому процессу выделяется одинаковый квант времени; 2) различные кванты времени (в зависимости от важности и т. д.). Допустим, что в состав ЭВМ входит таймер, и что он подключен к одному из входов, на которые поступают запросы на прерывание. Таким образом, условимся, что сигнал от таймера вызывает запись контекста в системный стек и загрузку в счётчик команд адреса, хранящегося в векторе прерывания. Назовём программу, определяющую этот вектор прерывания, программой предварительной обработки времени (ППОВ). Допустим, что таймер вырабатывает сигнал прерывания через каждые 2 мс, а нам нужен квант величиной 6 мс. ППОВ в этом случае подсчитает количество прерываний от таймера. После каждого третьего прерывания она должна вызывать диспетчер, чтобы он выполнил переключение процесса.
Pk
П П О В
Pk
1-е прерывание
П П О В 2-е
Pk
П П О В
D Pe
П П О В
Pe
П П О В
3-
Квант k
Квант e
Рис.4 Так происходит, если все готовые процессы хотят работать.
Если процесс вырабатывает команду “ждать”, то прерывание нарушает чередование квантов (следующему процессу достаётся часть кванта). В этом случае возможны две стратегии: 1) можно не принимать во внимание (в среднем); 2) после команды “ждать” всегда начинается подсчёт прерываний с нуля (квант будет целый). Допустим, что ППОВ использует некоторую переменную: “текущий квант”, в которую оно образует сумму числа прерываний. С вызовом D текущему кванту присвоится значение 0. Procedure Переключить; {Процедура вызывает ППОВ, не изменяя состояния процесса} Begin Передать контекст процесса (текущий процесс^.адрес стека); Выбрать; {Определяет новое значение “текущего процесса”} Загрузить контекст процесса (текущий процесс^.адрес стека); Переключить контекст; End. Возникает вопрос: как сохранять величину кванта? Возможны два случая. 1-й случай: Величина кванта хранится в дескрипторе процесса. Если процесс становится активный, то сам диспетчер будет определять, когда переключать процесс. Type связь = ^ дескриптор; связь1 = ^ процесс; связь2 = ^ стек; дескриптор = record следующий : связь; адрес процесса : связь1; адрес стека : связь2; состояние : boolean; приоритет : integer; max. время : integer; текущее время : integer; Procedure Переключить2; Begin текущий процесс^.текущее время := текущий процесс^.текущее время+1; If текущий процесс^.текущее время > текущий процесс^.max. время then begin текущий процесс^.текущее время := 0; Передать контекст процесса (текущий процесс^.адрес стека); Выбрать; Загрузить контекст процесса (текущий процесс^.адрес стека); End.
В системах общего назначения в основном используется режим разделения времени (интерактивный режим), а управление ведётся по времени, которое требует процесс для своего выполнения. Здесь могут применяться следующие принципы: 1) Принцип одинаковых услуг. Предполагает, что процессы выполняются в порядке времени их поступления (строится очередь процессов, выполняется первый процесс). Этот принцип был бы не плох, если бы процессы не приостанавливались (для ввода и т. д.). Время нахождения в системе зависит от времени поступления процесса. Время ожидания должно быть пропорционально времени обслуживания (должно быть так). 2) Принцип пропорциональности. Предполагает, что время нахождения в системе должно быть пропорционально времени выполнения процесса (короткие процессы получают преимущество). Может сложиться ситуация, что длинный процесс затеряется, если поступают всё время короткие. 3) Принцип скорейшего завершения. Из очереди выбирается тот процесс, у которого меньшее время до окончания. При каждом переключении процесса время контекста уменьшается на величину работы процесса. Существуют принципы управления с несколькими очередями и с очередями с обратной связью. Очередь с обратной связью учитывает изменение характеристик процесса в период их выполнения и в зависимости от них изменяет приоритет процесса. В качестве примера рассмотрим ситуацию: Допустим, что среди процессов определенных в системе, имеются процессы с большим числом операций ввода/вывода. Такие процессы позволяют хорошо испытывать режимы мультипрограммирования. Чтобы выявить и создать лучшие условия для выполнения таких процессов, создадим в системе вторую очередь, которую назовём очередью ввода/вывода. Условимся: всегда выполняется процесс из 2-й очереди. Возникают две задачи: 1. Какие процессы перевести из общей очереди во вторую очередь? Для решения этого вопроса введём для каждого процесса специальную переменную, в которой подсчитывается число обращений к вводу/выводу. 2. Если, например, число обращений больше двух, то процесс переводится в очередь с интенсивным вводом/выводом. Чтобы случайно не включить процесс с малым обращением к вводу/выводу в приоритетную очередь, условимся, что при каждом обращении к очереди ввода/вывода число обращений к этой очереди каждого процесса уменьшим на 1. Таким образом, если процесс, находящийся в очереди ввода/вывода, не обращается к вводу/выводу, то число обращений уменьшается. Если это число достигнет некоторого значения, то условимся процесс переводить из очереди ввода/вывода в общую очередь. Список рекомендуемой литературы Основная: 1. Хоар Ч.Взаимодействующие последовательные процессы.-М.,Мир,1989. 2. Векторизация программ: теория, методы, реализация. Сб. ст./Под ред.Г.Д.Чинина.- М.: Мир, 1991. 3. Дейтел Г. Введение в операционные системы.-Т.1,2.-М.:Мир,1989. 4. Остапенко Г.П. и др. Операционная система МОС ВП для СМ-1700.-М.:Финансы и статистика,1988. 5. Липаев В.В. Проектирование программируемых средств: Учеб. пособие.-М.:ВШ, 1990.
6. Лисс А.Р.,Селеджи Г.Ц. Программирование в системах реального времени: Учеб. пособие / ГЭТУ.- С.Пб., 1995. Дополнительная: 1. Джехани Н. Язык Ада.-М.:Мир,1988. 2. Джоунз Г. Программирование на языке ОККАМ.- М.: Мир,1989. 3. Малые ЭВМ высокой производительности.Архитектура и программирование.-М.:Радио и связь,1990. 4. Кун С. Матричные процессоры на СБИС.-М.: Мир,1991.
Редактор Т.Ю. Артюнина Подписано в печать 28.05.2001г. Формат 60х84 1/16. Усл.п.л. , уч.-изд. л. Тираж 60 экз. С. 37 Издательство ВСГТУ. Улан-Удэ, Ключевская, 40а Отпечатано в типографии ВСГТУ. Улан-Удэ, Ключевская, 42. ВСГТУ, 2001 г.