WikiSort.ru - Кино и мультфильмы

ПОИСК ПО САЙТУ | о проекте

Семафо́р (англ. 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();

См. также

Литература

  • Грегори Р. Эндрюс. Основы многопоточного, параллельного и распределённого программирования. — Вильямс, 2003.

Примечания

  1. Шаблон:Cite EWD (undated, 1962 or 1963)

Ссылки

Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".

Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.

Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .




Текст в блоке "Читать" взят с сайта "Википедия" и доступен по лицензии Creative Commons Attribution-ShareAlike; в отдельных случаях могут действовать дополнительные условия.

Другой контент может иметь иную лицензию. Перед использованием материалов сайта WikiSort.ru внимательно изучите правила лицензирования конкретных элементов наполнения сайта.

2019-2024
WikiSort.ru - проект по пересортировке и дополнению контента Википедии