Операционные системы
Самостоятельная работа №2
Исследование принципов реализации процессов и очередей многозадачного ядра
(вытесняющая многозадачность, принципы планирования процессов)
Цель работы: ознакомление с принципами реализации процессов и очередей в ядре многозадачной среды
Общие сведения
Реализация псевдопараллельного режима с помощью явного включения в пользовательские процессы оператора ПЕРЕДАТЬ_УПРАВЛЕНИЕ обладает недостатками:
- Пользовательские процессы включают в себя действия, которые по существу не относятся к их функциям;
- Интервалы процессорного времени, предоставляемые процессам, зависят от самих процессов и есть опасность захвата процессора на длительный срок одним процессом.
Поэтому в многозадачных системах используется принудительная передача управления. Моменты принудительной передачи управления определяются прерываниями от таймера. Такой способ передачи управления называется диспетчеризацией.
Работает многозадачная система с принудительной диспетчеризацией следующим образом.
Выполнение текущей сопрограммы приостанавливается прерыванием от таймера. Управление передается программе-обработчику прерывания. Обработчик выполняет действия по выбору следующей сопрограммы и передает управление ей оператором ПЕРЕДАТЬ_УПРАВЛЕНИЕ.
Таким образом каждой сопрограмме выделяется квант времени для выполнения.
Установка вектора прерывания в языке Pascal:
SetIntVec(IntNo : byte; Vector : pointer)где: IntNo – номер вектора прерывания; Vector – адрес процедуры-обработчика прерывания.
Чтение вектора прерывания в языке Pascal:
GetIntVec(IntNo : byte; Var Vector : pointer)где: IntNo – номер вектора прерывания; Vector – переменная, в которую пишется адрес процедуры-обработчика прерывания.
Примечание. Номер вектора прерывания от таймера – 8; номера свободных векторов для переустановки системного обработчика прерываний от таймера: 6016—6616; 7816—7F16.
Структура процедуры-обработчика прерывания:
Procedure Handler; interrupt; {обязательный атрибут}
Begin
...
End {Handler}.
Параллельно выполняемые в многозадачной среде процедуры называются процессами.
Поскольку процессор один, а процессов много, то появляется средство упорядочивания доступа процессов к процессору, принимающее форму очереди.
Важнейшим видом очереди является очередь процессов, готовых к выполнению.
Для обеспечения возможности включения процесса в очереди необходимо модифицировать дескриптор сопрограммы, реализующей процесс, введя в него поле – указатель на следующего.
С учетом возможности динамического создания и уничтожения представим процесс как объект следующего вида:
ПРОЦЕСС = ОБЪЕКТ
{ДАННЫЕ:} ЭЛЕМЕНТЫ ДЕСКРИПТОРА СОПРОГРАММЫ;
СЛЕДУЮЩИЙ;
АДРЕС_СТЕКА;
{МЕТОДЫ:} Procedure ИНИЦИАЛИЗИРОВАТЬ;
Procedure ОСВОБОДИТЬ_ПАМЯТЬ;
Procedure УСТАНОВИТЬ_СЛЕДУЮЩИЙ;
Function ПОЛУЧИТЬ_СЛЕДУЮЩИЙ;
КОНЕЦ;
Вторым видом объектов многозадачной среды является ОЧЕРЕДЬ, представляемая следующим описанием:
ОЧЕРЕДЬ = ОБЪЕКТ
{ДАННЫЕ:} НАЧАЛО;
{МЕТОДЫ:} Procedure ИНИЦИАЛИЗИРОВАТЬ;
Procedure ОСВОБОДИТЬ_ПАМЯТЬ;
Procedure ВКЛЮЧИТЬ_ПРОЦЕСС;
Procedure ИСКЛЮЧИТЬ_ПРОЦЕСС;
Function ПОЛУЧИТЬ_НАЧАЛО;
КОНЕЦ;
В данной работе рассматривается очередь готовых процессов, которая может быть представлена как тип, производный от типа ОЧЕРЕДЬ:
ОЧЕРЕДЬ_ГОТОВЫХ = ОБЪЕКТ(ОЧЕРЕДЬ)
{МЕТОДЫ:} Procedure ИНИЦИАЛИЗИРОВАТЬ;
Procedure ОСВОБОДИТЬ_ПАМЯТЬ;
Procedure ЗАПУСТИТЬ_ДИСПЕТЧЕР;
Procedure ОСТАНОВИТЬ_ДИСПЕТЧЕР;
Procedure ДОБАВИТЬ_НОВЫЙ_ПРОЦЕСС;
Procedure АКТИВИЗИРОВАТЬ_СЛЕДУЮЩИЙ;
КОНЕЦ;
Технология реализации процессов и очереди готовых процессов
Технология реализации процессов и очереди готовых процессов представлена в виде словесного описания библиотечного модуля, являющегося дальнейшим развитием предыдущей программы.
Unit DispObj;
Interface
Type
ПРОЦЕСС = ОБЪЕКТ
ЭЛЕМЕНТЫ ДЕСКРИПТОРА СОПРОГРАММЫ;
СЛЕДУЮЩИЙ;
АДРЕС_СТЕКА;
Procedure ИНИЦИАЛИЗИРОВАТЬ;
Procedure ОСВОБОДИТЬ_ПАМЯТЬ;
Procedure УСТАНОВИТЬ_СЛЕДУЮЩИЙ;
Function ПОЛУЧИТЬ_СЛЕДУЮЩИЙ;
КОНЕЦ;
ОЧЕРЕДЬ = ОБЪЕКТ
НАЧАЛО;
Procedure ИНИЦИАЛИЗИРОВАТЬ;
Procedure ОСВОБОДИТЬ_ПАМЯТЬ;
Procedure ВКЛЮЧИТЬ_ПРОЦЕСС;
Procedure ИСКЛЮЧИТЬ_ПРОЦЕСС;
Function ПОЛУЧИТЬ_НАЧАЛО;
КОНЕЦ;
ОЧЕРЕДЬ_ГОТОВЫХ = ОБЪЕКТ(ОЧЕРЕДЬ)
Procedure ИНИЦИАЛИЗИРОВАТЬ;
Procedure ОСВОБОДИТЬ_ПАМЯТЬ;
Procedure ЗАПУСТИТЬ_ДИСПЕТЧЕР;
Procedure ОСТАНОВИТЬ_ДИСПЕТЧЕР;
Procedure ДОБАВИТЬ_НОВЫЙ_ПРОЦЕСС;
Procedure АКТИВИЗИРОВАТЬ_СЛЕДУЮЩИЙ;
КОНЕЦ;
Var
ReadyList : ОЧЕРЕДЬ_ГОТОВЫХ;
Implementation
Procedure ЗАПРЕТИТЬ_ПРЕРЫВАНИЯ; Assembler;
Asm
...
End;
Procedure РАЗРЕШИТЬ_ПРЕРЫВАНИЯ; Assembler;
Asm
...
End;
Procedure СОЗДАТЬ_СОПРОГРАММУ;
Begin
...
End;
Procedure ПЕРЕДАТЬ_УПРАВЛЕНИЕ; Assembler;
Asm
...
End;
Procedure Handler; interrupt;
Begin
ЗАПРЕТИТЬ_ПРЕРЫВАНИЯ;
ReadyList.АКТИВИЗИРОВАТЬ_СЛЕДУЮЩИЙ;
End;
Procedure Idler; {всегда в очереди готовых}
Begin
while true do begin
end;
End;
Procedure ПРОЦЕСС.ИНИЦИАЛИЗИРОВАТЬ;
Begin
СОЗДАТЬ_СОПРОГРАММУ;
ЗАПОЛНИТЬ ПОЛЕ АДРЕС_СТЕКА;
End;
Procedure ПРОЦЕСС.ОСВОБОДИТЬ_ПАМЯТЬ;
Begin
ОСВОДИТЬ ПАМЯТЬ, ЗАНЯТУЮ ПОД СТЕК;
End;
Procedure ПРОЦЕСС.УСТАНОВИТЬ_СЛЕДУЮЩИЙ;
Begin
СЛЕДУЮЩИЙ := ... ;
End;
Function ПРОЦЕСС.ПОЛУЧИТЬ_СЛЕДУЮЩИЙ;
Begin
ПОЛУЧИТЬ_СЛЕДУЮЩИЙ := СЛЕДУЮЩИЙ;
End;
Procedure ОЧЕРЕДЬ.ИНИЦИАЛИЗИРОВАТЬ;
Begin
НАЧАЛО := NIL;
End;
Procedure ОЧЕРЕДЬ.ОСВОБОДИТЬ_ПАМЯТЬ;
Begin
{Цикл по всем процессам очереди}
ПРОЦЕСС.ОСВОБОДИТЬ_ПАМЯТЬ;
End;
Procedure ОЧЕРЕДЬ.ВКЛЮЧИТЬ_ПРОЦЕСС;
Begin
...
End;
Procedure ОЧЕРЕДЬ.ИСКЛЮЧИТЬ_ПРОЦЕСС;
Begin
...
End;
Function ОЧЕРЕДЬ.ПОЛУЧИТЬ_НАЧАЛО;
Begin
ПОЛУЧИТЬ_НАЧАЛО := НАЧАЛО;
End;
Procedure ОЧЕРЕДЬ_ГОТОВЫХ.ИНИЦИАЛИЗИРОВАТЬ;
Begin
ОЧЕРЕДЬ.ИНИЦИАЛИЗИРОВАТЬ;
End;
Procedure ОЧЕРЕДЬ_ГОТОВЫХ.ОСВОБОДИТЬ_ПАМЯТЬ;
Begin
ОЧЕРЕДЬ.ОСВОБОДИТЬ_ПАМЯТЬ;
End;
Procedure ОЧЕРЕДЬ_ГОТОВЫХ.ЗАПУСТИТЬ_ДИСПЕТЧЕР;
Begin
ЗАПРЕТИТЬ_ПРЕРЫВАНИЯ;
ПЕРЕУСТАНОВИТЬ_ВЕКТОР_ПРЕРЫВАНИЯ_ОТ_ТАЙМЕРА;
УСТАНОВИТЬ_НА_ВЕКТОР_8_ПРОЦЕДУРУ_Handler;
ПОЛУЧИТЬ_НАЧАЛО;
ИСКЛЮЧИТЬ_ПРОЦЕСС;
ПЕРЕДАТЬ_УПРАВЛЕНИЕ;
End;
Procedure ОЧЕРЕДЬ_ГОТОВЫХ.ОСТАНОВИТЬ_ДИСПЕТЧЕР;
Begin
ЗАПРЕТИТЬ_ПРЕРЫВАНИЯ;
ВОССТАНОВИТЬ_ВЕКТОР_ПРЕРЫВАНИЯ_ОТ_ТАЙМЕРА;
ПЕРЕДАТЬ_УПРАВЛЕНИЕ; {в главную программу}
End;
Procedure ОЧЕРЕДЬ_ГОТОВЫХ.ДОБАВИТЬ_НОВЫЙ_ПРОЦЕСС;
Begin
ЗАПРЕТИТЬ_ПРЕРЫВАНИЯ;
ПРОЦЕСС.ИНИЦИАЛИЗИРОВАТЬ;
ВКЛЮЧИТЬ_ПРОЦЕСС;
РАЗРЕШИТЬ_ПРЕРЫВАНИЯ;
End;
Procedure ОЧЕРЕДЬ_ГОТОВЫХ.АКТИВИЗИРОВАТЬ_СЛЕДУЮЩИЙ;
Begin
ЗАПРЕТИТЬ_ПРЕРЫВАНИЯ;
ВКЛЮЧИТЬ_ПРОЦЕСС; {текущий}
ПОЛУЧИТЬ_НАЧАЛО;
ИСКЛЮЧИТЬ_ПРОЦЕСС;
ПЕРЕДАТЬ_УПРАВЛЕНИЕ;
End;
Begin
ReadyList.ИНИЦИАЛИЗИРОВАТЬ;
ReadyList.ДОБАВИТЬ_НОВЫЙ_ПРОЦЕСС;{Включение Idler}
End.
С учетом приведенного библиотечного модуля пользовательская программа выглядит следующим образом:
Program User;
Uses Disp;
Procedure User_1;
Begin
while true do begin
...
end;
End;
Procedure User_N;
Begin
while true do begin
...
if УСЛОВИЕ then then begin {завершение выполнения}
ReadyList.ОСТАНОВИТЬ_ДИСПЕТЧЕР;
end;
end;
End;
Begin
ReadyList.ДОБАВИТЬ_НОВЫЙ_ПРОЦЕСС;{Включение User_1}
ReadyList.ДОБАВИТЬ_НОВЫЙ_ПРОЦЕСС;{Включение User_N}
ReadyList.ЗАПУСТИТЬ_ДИСПЕТЧЕР;
End.
Задание
- В соответствии с приведенными выше заготовками реализовать библиотечный модуль, обеспечивающий работу с очередью готовых процессов, учитывая динамическое выделение памяти под процессы.
- Составить пример, иллюстрирующий работу библиотечного модуля.
- Отчет должен содержать тексты программ библиотечного модуля и примера.