Семафо́р (англ. semaphore) — объект, ограничивающий количество потоков, которые могут войти в заданный участок кода. Определение введено Эдсгером Дейкстрой в 1962 или 1963 году[1]. Семафоры используются для синхронизации и защиты передачи данных через разделяемую память, а также для синхронизации работы процессов и потоков.
Семафор — это объект, над которым можно выполнить три операции.
Инициализация семафора (задать начальное значение счётчика):
init(n):
счётчик := n
Захват семафора (ждать, пока счётчик станет больше 0, после этого уменьшить счётчик на единицу):
enter():
счётчик := счётчик - 1
Освобождение семафора (увеличить счётчик на единицу):
leave():
счётчик := счётчик + 1
Предположим, что есть такой участок кода:
semaphore.init(5);
// .....
// .....
void DoSomething()
{
semaphore.enter();
// .......
semaphore.leave();
}
Тогда не более пяти потоков могут одновременно выполнять функцию DoSomething()
.
В более сложных семафорах может использоваться очередь; при этом потоки, ожидающие освобождения семафора, будут проходить через семафор именно в том порядке, в котором они вызывали enter()
.
Некоторые из проблем, которые могут решать семафоры:
Следующий пример показывает, как наладить поочерёдный доступ к консоли.
semaphore.init(1);
// Поток 1:
semaphore.enter();
cout << "Состояние массива: ";
for (int i=0; i<n; i++)
cout << a[i] << ' ';
cout << '\n';
semaphore.leave();
// Поток 2:
semaphore.enter();
cout << "Нажато Esc.\n";
semaphore.leave();
Этот код поможет предотвратить появление вывода наподобие
Состояние массива: 1 2 3 Нажато Esc. 4 5 6
Во-первых, можно написать программу с «утечкой семафора», вызвав enter()
и забыв вызвать leave()
. Реже встречаются ошибки, когда дважды вызывается leave()
.
Во-вторых, семафоры чреваты взаимной блокировкой потоков. В частности, опасен такой код:
// Поток 1:
semaphore1.enter();
semaphore2.enter();
// ...
semaphore2.leave();
semaphore1.leave();
// Поток 2:
semaphore2.enter();
semaphore1.enter();
// ...
semaphore1.leave();
semaphore2.leave();
Это заготовка статьи о компьютерах. Вы можете помочь проекту, дополнив её. Это примечание по возможности следует заменить более точным. |
Для улучшения этой статьи желательно: |
Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".
Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.
Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .