
- •Кафедра программного обеспечения информационных технологий
- •ТЕМА 1
- •1.1 Введение в операционные системы
- •1.1.1 Понятие операционной системы
- •1.1.2 Поколения ОС
- •1.1.3 Функции и свойства ОС
- •1.1.4 Характеристики современных ОС
- •1.1.5 Архитектура микроядра
- •1.1.6 Многопоточность
- •1.1.7 Симметричная многопроцессорность
- •1.1.8 Распределенные ОС
- •1.1.9 Объектно-ориентированный дизайн
- •1.1.10 Концепция ОС на основе микроядра
- •1.1.11 Принципы построения ОС
- •ТЕМА 2
- •2.1 Основы операционных систем
- •2.1.1 Понятие процесса
- •2.1.2 Понятие ресурса
- •2.1.3 Концепция виртуализации
- •2.1.5 Дисциплины распределения ресурсов
- •2.1.6 Концепция прерывания
- •ТЕМА 3
- •3.1 Процессы
- •3.1.1 Состояние процессов
- •3.1.2 Описание процессов
- •3.1.2.1 Структуры управления процессами
- •3.1.2.2 Управление процессами
- •3.1.3 Концепция потока как составной части процесса
- •3.1.4 Многопоточность
- •3.1.5 Однопоточная модель процесса
- •3.1.6 Многопоточная модель процесса
- •3.1.7 Функциональность потоков
- •3.1.8 Взаимодействие процессов
- •3.1.8.1 Задача взаимного исключения
- •3.1.8.2 Обобщенная задача взаимного исключения
- •3.1.9 Синхронизирующие примитивы (семафоры). Применение семафоров для решения задачи взаимного исключения
- •3.1.10 Задача “производитель-потребитель”
- •3.1.10.1 Общие семафоры
- •3.1.10.2 Задача “производитель-потребитель”, буфер неограниченного размера
- •3.1.10.3 Задача “производитель-потребитель”, буфер ограниченного размера
- •3.1.11 Взаимодействие через переменные состояния
- •3.1.12 Монитороподобные средства синхронизации
- •3.1.12.1 Введение
- •3.1.12.2 Механизм типа «критическая область»
- •3.1.12.3 Механизм типа «условная критическая область»
- •3.1.12.4 Вторая модификация механизма «критическая область» (модификация второго рода)
- •ТЕМА 4
- •4.1 Ресурсы
- •4.1.1 Распределение ресурсов. Проблема тупиков
- •4.1.2 Алгоритм банкира
- •4.1.3 Применение алгоритма банкира
- •ТЕМА 5
- •5.1 Память. Управление памятью
- •5.1.1 Требования к управлению памятью
- •5.1.2 Схемы распределения памяти
- •5.1.3 Система двойников при распределении памяти
- •ТЕМА 6
- •6.1 Организация виртуальной памяти
- •6.1.1 Структуризация адресного пространства виртуальной памяти
- •6.1.2 Задачи управления виртуальной памятью
- •6.1.2.1 Задача размещения
- •6.1.2.2 Задача перемещения
- •6.1.2.3 Задача преобразования
- •6.1.2.4 Задача замещения
- •ТЕМА 7
- •7.1 Планирование в операционных системах
- •7.1 Типы планирования процессора
- •7.2 Алгоритмы плинирования
- •7.3 Традиционное планирование в Unix
- •ТЕМА 8
- •8.1 Управление вводом-выводом и файлами
- •8.1.2 Развитие функций ввода-вывода
- •8.1.3 Управление ОС и устройствами ввода-вывода
- •8.1.4 Модели организации ввода-вывода
- •ТЕМА 9
- •9.1.1 Сегментация памяти
- •9.1.1.1 Сегментация памяти в процессорах 8086
- •9.1.1.3 Дескриптор сегмента
- •9.1.1.4 Дескрипторные таблицы
- •9.1.1.5 Селекторы сегментов в защищенном режиме
- •9.1.1.6 Локальные дескрипторные таблицы
- •9.1.1.7 Особенности сегментации
- •9.1.2 Страничная организация памяти
- •9.1.2.1 Страничный дескриптор
- •9.1.2.2 Разрешение и запрещение страничного преобразования
- •9.1.3 Организация защиты при работе процессора в защищенном режиме
- •9.1.3.1 Привилегированные команды
- •9.1.3.2 Защита доступа к данным
- •DPL- Descriptor Privilege Level
- •9.1.3.3 Защита сегмента кода
- •9.1.3.4 Определение текущего уровня привилегий
- •9.1.3.5 Передача управления между уровнями привилегий
- •9.1.3.6 Подчиненные сегменты
- •9.1.3.7 Шлюзы вызова
- •9.1.4 Поддержка многозадачности в процессорах архитектуры IA-32
- •9.1.4.1 Сегмент состояния задачи
- •9.1.4.2 Дескриптор сегмента TSS
- •9.1.4.3 Сегмент состояния задач TSS
- •9.1.4.4 События, которые могут вызвать переключение задачи
- •9.1.4.5 Формат шлюза задач
- •9.1.4.7 Особые случаи при переключении задач
- •9.1.4.8 Вложенность задач
- •9.1.4.9 Двоичная карта разрешения ввода-вывода
- •9.1.5 Прерывания и особые случаи
- •9.1.5.1 Прерывания и особые случаи в процессоре 8086
- •9.1.5.2 Прерывания в защищенном режиме
- •9.1.5.3 Дескрипторная таблица прерываний
- •9.1.5.4 Шлюз ловушки
- •9.1.5.5 Шлюз прерывания
- •9.1.5.6 Шлюз задачи
3.1.8 Взаимодействие процессов
3.1.8.1 Задача взаимного исключения
Если двум или более процессам необходимо взаимодействовать друг с другом, то они должны быть связаны, то есть иметь средства для обмена информацией. Предполагается, что процессы связаны слабо. Под этим подразумевается, что кроме достаточно редких моментов явной связи эти процессы рассматриваются как совершенно независимые друг от друга. В частности, не допускаются какие либо предположения об относительных скоростях различных процессов.
В качестве примера рассматривается два последовательных процесса, которые удобно считать циклическими. В каждом цикле выполнения процесса существует критический интервал. Это означает, что в любой момент времени только один процесс может находиться внутри своего критического интервала. Чтобы осуществить такое взаимное исключение, оба процесса имеют доступ к некоторому числу общих переменных. Операции проверки текущего значения такой общей переменной и присваивание нового значения общей переменной рассматриваются как неделимые. То есть, если два процесса осуществляют присваивание новое значение одной и той же общей переменной одновременно, то присваивание происходит друг за другом и окончательное значение переменной одному из присвоенных значений, но никак не их смеси. Если процесс поверяет значение переменной одновременно с присваиванием ей значения другим процессом, то первый процесс обнаруживает либо старое, либо новое значение, но никак не их смесь.
begin integer очередь;
очередь := 1; parbegin
процесс 1: begin
L1: if (очередь = 2) then goto L1;
критический интервал 1; очередь := 2; остаток цикла 1;
goto L1; end;
процесс 2: begin
L2: if (очередь = 1) then goto L2;
критический интервал 2; очередь := 1; остаток цикла 2;
goto L2;
45

end;
parend;
end;
int turn=1; void P0()
{
while (1)
{
while(turn!=0)
критический интервал 1; turn=1;
….
}
}
void P1()
{
while (1)
{
while(turn!=1)
критический интервал 2; turn=0;
….
}
}
void main()
{
parbegin(P0,P1);
}
Недостатки решения:
1.Процессы могут входить в критический интервал строго последовательно. Темпы развития задаются медленным процессом.
2.Если кто-то из процессов останется в остатке цикла, то он затормозит и второй процесс
Второй способ решения:
begin integer С1,С2; С1 := 1; С2 := 1;
parbegin
процесс 1: begin
46

L1: if (С2 = 0) then goto L1; С1 := 0;
критический интервал 1;
С1 := 1;
остаток цикла 1; goto L1;
end;
процесс 2: begin
L2: if (С1 = 0) then goto L2; С2 := 0;
критический интервал 2;
С2 := 1;
остаток цикла 2; goto L2;
end;
parend;
end;
int flag[2]; void P0()
{
while (1)
{
while (flag[1]); flag[0]=1;
критический интервал 1; flag[0]=0;
….
}
}
void P1()
{
while (1)
{
while (flag[0]); flag[1]=1;
критический интервал 2; flag[1]=0;
….
}
}
void main()
{
47

flag[0]=0;
flag[1]=0;
parbegin(P0,P1);
}
Недостаток: принципиально при развитии процессов строго синхронно они могут одновременно войти в критический интервал.
Было предложено следующее решение (вариант 3)::
begin integer С1,С2; С1 := 1; С2 := 1;
parbegin
процесс 1: begin
А1: С1 := 0;
L1: if (С2 = 0) then goto L1;
критический интервал 1;
С1 := 1;
остаток цикла 1; goto А1;
end;
процесс 2: begin
А2: С2 := 0;
L2 if (С1 = 0) then goto L2;
критический интервал 2;
С2 := 1;
остаток цикла 2; goto А2;
end;
parend;
end;
int flag[2]; void P0()
{
while (1)
{
flag[0]=1; while (flag[1]);
критический интервал 1; flag[0]=0;
….
48
}
}
void P1()
{
while (1)
{
flag[1]=1; while (flag[0]);
критический интервал 2; flag[1]=0;
….
}
}
void main()
{
flag[0]=0;
flag[1]=0;
parbegin(P0,P1);
}
Недостаток: возникает другая проблема – может бесконечно долго решаться вопрос о том, кто первым войдет в критический интервал.
Решение 4.
begin integer С1,С2; С1 := 1; С2 := 1;
parbegin
процесс 1: begin L1: С1 := 0;
if (С2 = 0) then begin
C1 := 1; goto L1;
end;
критический интервал 1;
С1 := 1;
остаток цикла 1; goto L1;
end;
процесс 2: begin L2: С2 := 0;
if (С1 = 0) then begin
C2 := 1;
49

goto L2; end;
критический интервал 2;
С2 := 1;
остаток цикла 2; goto L2;
end;
parend;
end;
int flag[2]; void P0()
{
while (1)
{
flag[0]=1; while (flag[1]);
{
flag[0]=0;
задержка; flag[0]=1;
}
критический интервал 1; flag[0]=0;
….
}
}
void P1()
{
while (1)
{
flag[1]=1; while (flag[0]);
{
flag[1]=0;
задержка; flag[1]=1;
}
критический интервал 2; flag[1]=0;
….
}
}
50
void main()
{
flag[0]=0;
flag[1]=0;
parbegin(P0,P1);
}
Решение задачи взаимного исключения. Алгоритм Деккера.
begin integer С1,С2,очередь; С1 := 1; С2 := 1;
очередь := 1; parbegin
процесс 1: begin
А1: С1 := 0;
L1: if (С2 = 0) then begin
if (очередь = 1) then goto L1; C1 := 1;
B1: if (очередь = 2) then goto B1; goto А1;
end;
критический интервал 1; очередь := 2;
С1 := 1;
остаток цикла 1; goto А1;
end;
процесс 2: begin
А2: С2 := 0;
L2: if (С1 = 0) then begin
if (очередь = 2) then goto L2; C2 := 1;
B2: if (очередь = 1) then goto B2; goto А2;
end;
критический интервал 2; очередь := 1;
С2 := 1;
остаток цикла 2; goto А2;
end;
parend;
end;
51

int flag[2], turn; void P0()
{
while (1)
{
flag[0]=1; while (flag[1]);
{
if (turn==1)
{
flag[0]=0; while (turn==1); flag[0]=1;
}
}
критический интервал 1; turn=1;
flag[0]=0;
….
}
}
void P1()
{
while (1)
{
flag[1]=1; while (flag[0]);
{
if (turn==0)
{
flag[1]=0; while (turn==0); flag[1]=1;
}
}
критический интервал 2; turn=0;
flag[1]=0;
….
}
}
void main()
52
{
flag[0]=0;
flag[1]=0;
turn=1;
parbegin(P0,P1);
}
Решение задачи взаимного исключения. Алгоритм Пэтерсона..
int flag[2], turn; void P0()
{
while (1)
{
flag[0]=1; turn=1;
while (flag[1] && (turn==1));
критический интервал 1; flag[0]=0;
….
}
}
void P1()
{
while (1)
{
flag[1]=1; turn=0;
while (flag[0] && (turn==0));
критический интервал 2; flag[1]=0;
….
}
}
void main()
{
flag[0]=0;
flag[1]=0;
parbegin(P0,P1);
}
Для доказательства корректности задачи взаимного исключения необходимо проверить три положения.
1. Решение безопасно в том смысле, что два процесса не могут одновременно оказаться в своих критических интервалах
53