Компонент Semaphore

Дата обновления перевода 2023-08-25

Компонент Semaphore

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

Установка

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.