Проблемы синхронизации процессов. Способы синхронизации
Синхронизация процессов и потоков.
Синхронизация – это согласование скоростей потоков путем приостановки потока до наступления какого-то события и его последующей активизации при наступлении этого события.
IPC (Inter Process Communication)
|
Синхронизация может выполняться как средствами ОС, так и быть встроенной в программу.
Необходимость синхронизации и гонки.
Рассмотрим пример:
2-а процесса борются за один ресурс.
Клиент N
Описание ситуации:
1. Поток А обновляет поле «Заказ» записи о клиенте N. Он выполняет шаг А1. шаг А2 изменяет значение поля «Заказ». Выполнение прерывается из-за завершения кванта.
2. Поток В выполняет операцию внесения данных об оплате клиентом N. Он успевает выполнить шаг В1 и В2 до своего прерывания.
3. Управление передается потоку А, выполняется шаг А3 и запись переносится в файл.
4. Когда управление передается потоку В, он выполняет шаг В3. Данные о «Заказе» потока А заменяются на устаревшие.
Может возникнуть и обратная ситуация, может быть потеряна информация поля «Оплата».
Ситуация, когда два или более процесса обрабатывают разделяемые данные и неконечный результат зависит от соотношения скоростей потоков, называется «Гонкой».
Критическая секция:
Это часть программы, результат выполнения которой может меняться, если переменные относящиеся к этой части программы изменяются другими потоками, пока ее выполнение еще не завершено.
Чтобы исключить эффект «Гонок» по отношению к критическим данным, необходимо чтобы в каждый момент времени в критической секции, связанной с этими данными находился только 1 поток, это метод Взаимного Исключения.
Простейший вариант реализации: это возможность запрета любых прерываний потоков при ее нахождении в критической секции.
Блокирующие переменные.
Глобальные переменные - это переменные, к которым все потоки имеют доступ.
Алгоритм использования блокирующих переменных:
Продолжить выполнение
Каждому набору критических данных ставится соответствующая двоичная переменная, которая =0 при нахождении в критической ситуации, и =1, если ресурс свободен.
Проверки значения переменной и занятия ресурса должны быть не делимой операцией.
Недостаток: неэффективность использования процессов времени в цикле проверки значения переменной. Для решения этой проблемы в ОС применяются специальные системные вызовы для работы с критическими секциями.
Семафоры.
Дийкстра (Dykstra) – это переменные, которые могут принимать целые неотрицательные значения. Для работы с семафорами используются 2 примитива, обозначаемые P и V. Сама переменная семафор – S.
С ней выполняются следующие действия:
1. V(S): S: =S+1
Единым неделимым действиям.
2. P(S): S: = S-1
Если это возможно. Если S: =0, то поток ждет пока это уменьшение станет возможным. Операция неделимая.
Пример:
Работа семафора на примере двух потоков при помощи буфера.
потоки-писатели потоки-читатели
Для правильной совместной работы, поток-писатель должен остановиться, когда все записи в буфере заняты, и активироваться при освобождении хотя бы одного буфера.
Напротив, поток-читатель останавливается, когда все буферы пусты, и активируется при появлении хотя бы одной записи.
Буфер состоит из буферов N.
Введем семафоры e и f.
e – свободные;
f – занятые.
В начальный момент времени e = N, f = 0: потоки-писатели выполняют операцию P(e).
Такая схема позволяет эффективно и с минимальными затратами решить сложную задачу.
В частном случае, если переменная S принимает значение 0 и 1: S = {0,1}, то семафор вырождается в блокирующую переменную (двоичный семафор).