Компонент Семафор

Дата обновления перевода 2021-07-15

Компонент Семафор

Компонент Semaphore управляет семафорами, механизмом для предоставления эксклюзивного доступа к общему ресурсу.

5.2

Компонент Семафор был представлен в Symfony 5.2.

Установка

1
$ composer require symfony/semaphore

Note

Если вы устанавливаете этот компонент вне приложения Symfony, вам нужно подключить файл vendor/autoload.php в вашем коде для включения механизма автозагрузки классов, предоставляемых Composer. Детальнее читайте в этой статье.

Использование

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

Создайте семфоры с классом SemaphoreFactory, который, в свою очередь, требует другой класс для управления хранилищем:

1
2
3
4
5
6
7
8
use Symfony\Component\Semaphore\SemaphoreFactory;
use Symfony\Component\Semaphore\Store\RedisStore;

$redis = new Redis();
$redis->connect('172.17.0.2');

$store = new RedisStore($redis);
$factory = new SemaphoreFactory($store);

Семфор создается путем вызова метода createSemaphore(). Его первый аргумент - произвольная строка, которая представляет блокированный ресурс. Его второй аргумент - макисмальное количество допустимых процессов. Затем, вызов к методу acquire() будет пробовать получить семафор:

1
2
3
4
5
6
7
8
9
// ...
$semaphore = $factory->createSemaphore('pdf-invoice-generation', 2);

if ($semaphore->acquire()) {
    // Ресурс "pdf-invoice-generation" заблокирован.
    // Здесь вы можете безопасно вычислисть и сгенерировать инвойс.

    $semaphore->release();
}

Если семафор не может быть получен, метод возвращает false. Метод acquire() может безопасно быть вызван множество раз, даже если семафор уже получен.

Note

В отличие от других реализаций, компонент Семафор различает экземпляры семфоров даже если они созданы для одного ресурса. Если семафор должен быть использован несколькими сервисами, они должны иметь один экземпляр Semaphore, возвращенный методом SemaphoreFactory::createSemaphore.

Tip

Если вы не выпустите семафор ясно, он будет выпущен автоматически при разрушении экземпляра. В некоторых случаях, это может быть полезно для блокировки ресурса в нескольких запросах. Чтобы отключить поведение автоматического выпуска, установите пятый аргумент метода createSemaphore() как false.