
- •1. Понятие операционной системы и цели ее работы
- •Компоненты компьютерной системы
- •Общая картина функционирования компьютерной системы
- •Классификация компьютерных систем
- •Классификация компьютерных архитектур
- •История ос
- •Отечественные операционные системы
- •Облачные вычисления и ос для облачных вычислений(развитие концепций и возможностей ос)
- •Вопрос 2
- •Особенности операционных систем для компьютеров общего назначения (mainframes)
- •Режим разделения времени и особенности ос с режимом разделения времени
- •Системы и ос реального времени
- •Особенности ос для персональных компьютеров
- •Карманные компьютеры (handhelds) и их ос
- •Параллельные компьютерные системы и особенности их ос.
- •Симметричные и асимметричные мультипроцессорные системы
- •Распределенные компьютерные системы и особенности их ос
- •Виды серверов в клиент-серверных компьютерных системах
- •Кластерные вычислительные системы и их ос
- •3. Вычислительные среды
- •Архитектура компьютерной системы
- •Функционирование компьютерной системы
- •Обработка прерываний
- •Архитектура ввода-вывода
- •Вопрос 4
- •Структура памяти
- •Аппаратная защита памяти и процессора
- •Аппаратная защита адресов памяти в системах с теговой архитектурой
- •Организация аппаратной защиты памяти и процессора
- •5. Основные компоненты ос
- •Исполнение программ в ms dos
- •Исполнение нескольких программ в unix
- •Коммуникационные модели
- •6. Уровни абстракции
- •Уровни абстракции ос
- •Структура системы ms dos
- •Структура системы unix
- •Операционные системы с микроядром
- •Виртуальная машина Java (jvm)
- •Цели проектирования и разработки ос
- •Механизмы и политики
- •Реализация операционных систем
- •Генерация операционной системы
- •7. Понятие процесса
- •Состояния процесса
- •Блок управления процессом
- •Переключение с одного процесса на другой
- •Очереди, связанные с диспетчеризацией процессов
- •Переключение контекста
- •Вопрос 8
- •Уничтожение процесса
- •Парадигма (шаблон) взаимодействия процессов: производитель – потребитель
- •9. Коммуникация процессов
- •Непосредственная коммуникация процессов
- •Косвенная коммуникация процессов (про синхронизацию есть немного)
- •Буферизация и очередь сообщений (сокеты)
- •Основные понятия диспетчеризации процессов
- •Вопрос 10 Однопоточные и многопоточные процессы
- •Проблемы многопоточности
- •Потоки posix (Pthreads
- •Потоки в Java
- •Вопрос 12 Основные понятия диспетчеризации процессов
- •Планировщик процессора
- •Критерии диспетчеризации
- •Предсказание длины следующего периода активности
- •Вопрос 13 Диспетчеризация по приоритетам
- •Стратегия Round Robin (rr)
- •Многоуровневая очередь
- •Многоуровневые аналитические очереди
- •Планирование в Solaris
- •Планирование в Windows 2000
- •Вопрос 14 История синхронизации
- •Синхронизация процессов по критическим секциям
- •Алгоритм решения проблемы критической секции
- •Вопрос 15 Синхронизация на основе общих семафоров
- •Семафоры как общее средство синхронизации
- •Общие и двоичные семафоры
- •Решение классических задач синхронизации с помощью семафоров
- •Вопрос 16
- •Мониторы
- •Синхронизация в ос Solaris
- •Синхронизация в Windows 2000
- •Вопрос 17 Проблема тупиков
- •Модель системы
- •Граф распределения ресурсов
- •Поиск тупиков по графу распределения ресурсов
- •Методы обработки тупиков
- •Предотвращение тупиков
- •Избежание тупиков
- •Безопасное состояние системы
- •Вопрос 18
- •19. Управление памятью.
- •Вопрос 20
- •Вопрос 22
- •23. Понятие файла
- •Вопрос 24
Синхронизация процессов по критическим секциям
Рассмотрим проанализированную проблему в общем виде. Пусть имеются n параллельных процессов, каждый из которых может обратиться к общим для них данным. Назовем критической секцией фрагмент кода каждого процесса, в котором происходит обращение к общим данным. Проблема синхронизации процессов по критическим секциям заключается в том, чтобы обеспечить следующий режим выполнения: если один процесс вошел в свою критическую секцию, то до ее завершения никакой другой процесс не смог бы одновременно войти в свою критическую секцию.
Можно показать, что для решения проблемы критической секции необходимо и достаточно выполнение следующих трех условий:
Взаимное исключение. Если некоторый процесс исполняет свою критическую секцию, то никакой другой процесс не должен в этот момент исполнять свою.
Прогресс.Если в данный момент нет процессов, исполняющих критическую секцию, но есть несколько процессов, желающих начать исполнение критической секции, то выбор системой процесса, которому будет разрешен запуск критической секции, не может продолжаться бесконечно.
Ограниченное ожидание.В системе должно существовать ограничение на число раз, которое процессам разрешено входить в свои критические секции, начиная от момента, когда некоторый процесс сделал запрос о входе в критическую секцию, и до момента, когда этот запрос удовлетворен.
Алгоритм решения проблемы критической секции
Пусть для простоты имеется только два процесса – P0 и P1. Общая структура i - го процесса должна иметь вид:
do {
вход в критическую секцию
критическая секция
выход из критической секции
остальная часть кода
} while (1)
Процессы могут использовать общие переменные для синхронизации своих действий.
Алгоритм 1.Предпримем первую попытку решения проблемы. Введем целую переменную turn (очередь), значение которой turn == i будет обозначать, что наступила очередь процесса номер i войти в свою критическую секцию. Первоначально turn == 0.
Алгоритм процесса Pi имеет вид:
do {
while (turn != i);
критическая секция
turn = j; /* j != i: если i == 0, j == 1; если i == 1, j == 0 */
остальная часть кода
} while (1)
Очевидно по построению, что данный алгоритм удовлетворяет принципу взаимное исключение. Однако он не удовлетворяет принципу прогресс: алгоритм не предпринимает никаких мер, чтобы ограничить время выбора процесса, желающего начать критическую секцию. Причина в следующем: алгоритм не хранит информацию о том, какие процессы желают войти в свои критические секции.
Алгоритм 2.Будем хранить не номер процесса, допущенного к критической секции, а массив булевских флагов flag [2], такой, что flag[i] == true, если i -й процесс готов войти в свою критическую секцию. Алгоритм процесса Pi примет вид:
do {
flag[i] = true;
while (flag[j]); /* j!=i: если i==0, j==1; если i == 1, j == 0 */
критическая секция
flag[i] = false;
остальная часть кода
} while (1)
Данный вариант алгоритма также удовлетворяет принципу взаимного исключения, так как перед входом в критическую секцию процесс ждет, пока не останется других процессов, желающих войти в свои критические секции.
Однако данный алгоритм также не удовлетворяет принципу прогресс, Причина в том, что алгоритм не различает информацию о том, что процесс еще только готов войти в свою критическую секцию, и о том, что он в нее уже вошел.
Алгоритм 3.Модифицируем алгоритм, используя в нем одновременно и переменную turn, и массив флагов flag. Алгоритм процесса примет вид:
do {
flag[i] = true;
turn = j;
while (flag[j] and turn == j);
критическая секция
flag[i] = false;
остальная часть кода
} while (1)
Идея данного варианта алгоритма в том, что перед входом в критическую секцию процесс сначала заявляет о своем намерении в нее войти, но затем пытается предоставить право на вход в критическую секцию другому процессу и только после того, как другой процесс ее выполнил и больше не желает в нее войти, входит сам в свою критическую секцию.
Алгоритм булочной (bakery algorithm)
Автор данного алгоритма – Л. Лампорт (L. Lamport). Рассмотрим другой алгоритм, решающий проблему синхронизации по критическим секциям. Происхождение названия следующее: алгоритм как бы воспроизводит стратегию автомата в (американской) булочной, где каждому клиенту присваивается его номер в очереди. В нашей российской реальности, данный алгоритм более уместно было бы назвать по этой же причине "алгоритм Сбербанка".
В алгоритме для n процессов используется булевский массив choosing[n]:значение choosing[i] == true будет означать, что в данный момент система определяет номер в очереди i -го процесса. Используется также целочисленный массив number[n]: number[i] будет обозначать вычисленный порядковый номер в очереди (приоритет) i- го процесса.
Алгоритм булочной (для i -го процесса) имеет вид:
do {
choosing[i] = true;
number [i] = max (number[0], number[1], …, number[n-1]) + 1;
choosing[i] = false;
for (j = 0; j < n; j++) {
while choosing[j];
while ((number[j] != 0) && (number[j] < number[i]));
}
критическая секция
number [i] = 0;
остальная часть кода
} while (1)
По построению, номер, присваиваемый процессу, будет гарантированно больше, чем номер любого другого процесса в системе. Прежде чем войти в критическую секцию, процесс ждет, пока завершится процесс выбора номера для всех процессов и пока в системе есть хотя бы один выбранный процесс, номер которого меньше. По окончании критической секции процесс обнуляет свой номер. Данный алгоритм также решает проблему синхронизации процессов по критическим секциям.
Синхронизация на основе аппаратной поддержки атомарных операций
Рассмотренные алгоритмы синхронизации, не использующие каких-либо специальных синхронизирующих примитивов, достаточно сложны для понимания, разработки и сопровождения. Более простым (с точки зрения разработчика программ) решением для синхронизации была бы аппаратная и системная поддержка каких-либо простых атомарных операций, на основе которой реализовать синхронизацию процессов было бы проще.
Рассмотрим одну из этих операций, традиционно используемых для синхронизации, - операцию TestAndSet, которая атомарно выполняет считывание и запоминание значения переменной, затем изменяет его на заданное значение, но в результате выдает первоначальное значение переменной.
Предположим, что в системе имеется аппаратная поддержка следующей атомарной операции:
boolean TestAndSet (boolean & target) {
boolean rv = target;
target = true;
return rv;
}
С помощью данной операции реализовать синхронизацию процессов по критическим секциям очень просто. Введем в качестве блокировщика общую булевскую переменную:
boolean lock = false;
Код i -го процесса будет иметь вид:
do{
while(TestAndSet(lock));
критическаясекция
lock=false;
остальная часть кода
} while (1)
Значение переменной lock, равное true,означает, что вход в критическую секцию заблокирован. Каждый процесс ждет, пока он не разблокируется, затем, в свою очередь, выполняет блокировку и входит в критическую секцию. При ее завершении процесс разблокирует критическую секцию присваиванием lock значения false.
Другое распространенное аппаратное решение для синхронизации – атомарная операция Swap, выполняющая перестановку значений двух переменных:
void Swap (Boolean * a, Boolean * b) {
Boolean temp = * a;
a = * b;
* b = temp;
}
Взаимное исключение по критическим секциям с помощью атомарной операции Swap реализуется следующим образом (приведен код i -го процесса) :
/* общиеданные */
boolean lock = false;
Boolean key = false;
/* кодпроцесса i */
do {
key = true;
while (key) {
Swap(&lock, &key);
}
критическаясекция
lock=false;
остальная часть кода
} while (1)
При данной реализации, условием ожидания процесса перед входом в критическую секцию является условия (key == true),которое фактически означает то же, что и в предыдущей реализации, - закрытое состояние блокировщика, т.е., то, что другой процесс находится в своей критической секции. Когда критическая секция освободится (освобождение осуществляется присваиванием lock = false после завершения критической секции в исполнившем ее процессе), ее начнет исполнять текущий процесс.