Семафоры, мьютексы. Решение задач Читатель-Писатель и Производитель-Потребитель с помощью семафоров.

 

Семафор — целочисл. неотр. переменная, на которой определены две атомарные операции (атомарность обеспечивается реализацией).

V(S) — S++; // Неблокирующая — независимо от состояния S увеличиваем на 1 и идем дальше.

P(S) — S--; // Блокирующая — если S=0, поток будет ожидать его увеличения.

 

Типы семафоров:

1. Двоичные семафоры. Используются для обеспечения эксклюзивного доступа к ресурсу (решение задачи вз. искл.). Если S=1, ресурс свободен, S=0 — занят. Начальное значение — 1.

 

Semaphore S=1;

while (true ) {

P(S); // Захват ресурса в эксклюзивное пользование.

CS();

V(S); // Освобождение.

NCS();

}

 

2. Счетные семафоры — используются для контроля количества доступных ресурсов. Значение семафора — текущее количество свободных единиц ресурсов. Начальное значение — общее кол-во единиц ресурсов.

Пусть даны пять принтеров.

 

Semaphore S1=5, S2=1;

while (true ) {

P(S1); // Резервирование единицы ресурсов.

P(S2); // Получение эксклюзивного доступа к структуре, описывающей принтер.

Выбор принтера ();

V(S2);

Печать();

P(S2);

Освобождение принтера();

V(S2);

V(S1);

}

 

3. Мьютексы — специальный тип двоичных семафоров. Объект синхронизации, который может находиться в одном из двух состояний: свободен и занят. Определены две операции:

lock() / unlock()

acquire() / release()

___

 

Mutex M=unlocked;

while (true ) {

acquire(M);

CS();

release(m);

NCS();

}

 

Дополнительные свойства Мьютекса:

  1. Запоминание владельца. Освободить мьютекс может только тот поток, который его захватил.
  2. Рекурсивность. Поток, захвативший мьютекс, может повторно его захватить произвольное число раз. Для освобождения нужно соответсвующее число раз вызвать release.