Семафор (інформатика)

Семафор - об'єкт, який дозволяє увійти в задану ділянку коду не більше ніж n потокам. Визначення введено Едсгером Дейкстри.
Семафори використовуються при передачі даних через поділювану пам'ять.


1. Визначення семафора

Семафор - це об'єкт, з яким можна виконати три операції.

 init (n): лічильник: = n enter (): чекати поки лічильник стане більше 0; після цього зменшити лічильник на одиницю. leave (): збільшити лічильник на одиницю. 

Припустимо, що є така ділянка коду:

 semaphore.init (5); ..... ..... void DoSomething (void) {semaphore.enter (); ....... semaphore.leave ();} 

Тоді не більше п'яти потоків можуть одночасно виконувати функцію DoSomething ().

У більш складних семафор може використовуватися чергу; при цьому потоки, які очікують звільнення семафора, будуть проходити через семафор саме в тому порядку, в якому вони викликали enter ().


2. Застосування семафорів

Ось деякі з проблем, які можуть вирішувати семафори.

  • заборона одночасного виконання заданих ділянок коду;
  • почерговий доступ до критичного ресурсу (важливого ресурсу, для якого неможливий одночасний доступ).

Наступний приклад показує, як налагодити почерговий доступ до консолі.

 semaphore.init (1); 
 Потік 1: semaphore.enter (); cout << "Стан масиву:"; for (int i = 0; i 
 Потік 2: semaphore.enter (); cout << "натисненні Esc. \ N"; semaphore.leave (); 

Цей код допоможе запобігти появі лістингу на зразок

 Стан масиву: 1 2 3 натисненні Esc. 4 5 6 

3. Проблеми семафорів

По-перше, можна написати програму з "витоком семафора", викликавши enter () і забувши викликати leave (). Рідше зустрічаються помилки, коли двічі викликається leave ().

По-друге, семафори чреваті взаємним блокуванням потоків. Зокрема, небезпечний такий код:

 Потік 1: semaphore1.enter (); semaphore2.enter (); ... semaphore2.leave (); semaphore1.leave (); 
 Потік 2: semaphore2.enter (); semaphore1.enter (); ... semaphore1.leave (); semaphore2.leave (); 

Література

Грегорі Р. Ендрюс "Основи багатопотокового, паралельного та розподіленого програмування"