Поделиться через


Семафоры

Обновлен: Ноябрь 2007

Класс Semaphore представляет именованный (уровень всей системы) или локальный семафор. Семафоры Windows являются семафорами счета, которые могут использоваться для управления доступом к пулу ресурсов.

Управление ограниченным ресурсом

Потоки входят в семафор посредством вызова метода WaitOne, который наследуется из класса WaitHandle. При возвращении вызова счетчик на семафоре уменьшается. Если при запросе потоком записи счетчик равен нулю, поток блокируется. Потоки освобождают семафор посредством вызова метода Release, после чего открывается доступ для заблокированных потоков. Гарантированный порядок, в котором бы блокированные потоки входили в семафор (например, FIFO или LIFO), отсутствует.

Поток может выполнять вход в семафор несколько раз, вызывая многократно метод WaitOne. Чтобы освободить семафор, поток может вызвать перегрузку метода Release() то же количество раз или вызвать перегрузку метода Release(Int32) и указать количество освобождаемых записей.

Семафоры и идентификация потоков

Класс Semaphore не обеспечивает идентификацию вызовов методов WaitOne и Release. Например, обычным сценарием использования семафора является наличие потока производителя и потока получателя, когда один поток всегда увеличивает счетчик семафора, а другой всегда его уменьшает.

Обеспечить, чтобы поток не освобождали семафор слишком много раз — ответственность программиста. Предположим, что у семафора максимальное значение счетчика равно двум, и два потока A и B входят в семафор. Если ошибка программирования в потоке B заставляет его вызывать метод Release дважды, оба вызова завершаются успешно. Счетчик на семафоре достиг максимального значения, и если поток A вызовет метод Release, будет выдано исключение SemaphoreFullException.

Именованные семафоры

Операционная система Windows позволяет присваивать семафорам имена. Именованный семафор относится ко всей системе. То есть после создания именованного семафора он становится видимым во всех потоках и во всех процессах. Поэтому именованный семафор может использоваться для синхронизации действий процессов и потоков.

Можно создать объект Semaphore, который представляет именованный системный семафор с помощью одного из конструкторов, указывающих имя.

z6zx288a.alert_note(ru-ru,VS.90).gifПримечание.

Так как именованные семафоры относятся ко всей системе, можно иметь несколько объектов Semaphore, которые будут представлять один и тот же именованный семафор. Каждый раз при вызове конструктора или метода OpenExisting создается новый объект Semaphore. Указание того же имени повторно создает несколько объектов, которые представляют тот же именованный семафор.

При использовании именованных семафоров следует соблюдать осторожность. Так как они относятся ко всей системе, другой процесс, использующий то же имя, может неожиданно войти в семафор. Вредоносный код, выполняемый на том же компьютере, может использовать это как основу для атак по типу "отказ в обслуживании".

Используйте безопасность управления доступом для защиты объекта Semaphore, который представляет именованный семафор, предпочтительнее с помощью конструктора, который указывает объект SemaphoreSecurity. Также можно использовать безопасность управления доступом с помощью метода SetAccessControl, однако это оставит брешь в защите между временем создания семафора и временем начала действия его защиты. Защита семафоров с помощью безопасности управления доступом способствует предотвращению вредоносных атак, но не решает проблем, связанных с непреднамеренным конфликтом имен.

См. также

Ссылки

Semaphore

Другие ресурсы

Объекты и функциональные возможности работы с потоками