Часть программы, в которой осуществляется доступ к разделяемому ресурсу, называется критической секцией. Для исключения «эффекта гонок» по отношению к ресурсу, необходимо, что бы в каждый момент времени к критической секции, связанной с этим ресурсом, находился только один процесс (взаимное исключение).
С каждым ресурсом связывается двоичная переменная, принимающая значения 1 – если ресурс свободен, и 0 – если занят.
Алгоритм работы секции
Запрос к ресурсу D
Ресурс D свободен?
F(D)==1
Занять ресурс
F(D):=0
Критическая секция
Освободить ресурс
F(D):=1
POST(D)
WAIT(D)
да
Нет
F(D)=0
К высоко уровненным средствам синхронизации относятся семафоры.
Семафор (S) - это неотрицательная целая переменная, над которой возможны два вида операций.
§ P(S) – уменьшает S на единицу, если это возможно. Если нет – то процесс, вызвавший P-операцию ждёт пока не сможет уменьшить S.
§ V(S) – увеличивает S на единицу одним неделимым действием.
Когда семафор S принимает значение только 0 или 1, он превращается в блокирующую переменную.
Пример:
Буферный пул состоит из N буферов, по одной записи в каждом. Используется процесс-писатель и процесс-читатель.
Семафора:
e – число пустых буферов
f – число заполненных буферов
b – организация взаимного исключения
int N =256;
int e=N, f=0, b=1;
void Writer() //процесс-писатель
{
while(1)
{
PrepareNextRecord();
P(e); //уменьшить число свободных
P(b); //войти в секцию
AddToBuffer();
V(b); //выйти из секции
V(f); //увеличить число заполненных
}
}
void Read()//процесс-читатель
{
while(1)
{
P(f); //уменьшить число занятых
P(b); //войти в секцию
GetFromBuffer();
V(b); //выйти из секции
V(e); //увеличить число свободных
ProcessRecord();
}
}
Типовые ситуации в использовании семафоров:
1. Взаимное исключение на семафоре – используется двоичный семафор с начальным значением 1. Критические секции кодов всех процессов-участников начинаются с операцией P(S), заканчиваются V(S).
2. Синхронизация на семафоре – используется двоичный семафор с начальным значением 0 (событие ещё не наступило). Процесс, анализирующий наступление события, выполняет операцию V(S), процесс ожидающий наступление события – P(S). Если наступление события ожидают несколько процессов, то каждый из них, выполнив операцию P(S), должен так же выполнить операцию V(S).
3. Семафор как счётчик ресурсов. Для контроля N единиц ресурсов используется семафор S с начальным значением N. Выделение ресурсов сопровождается операцией P(S), освобождение – V(S).