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

Дата оновлення перекладу 2022-11-12

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

Компонент Семафор управляє семафорами - механізмом для надання ексклюзивного доступу до спільного ресурсу.

Установка

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.