PHP 8.6.0 Beta 1 is available for testing

Класс Swoole\Coroutine\Lock

(No version information available, might only be in Git)

Введение

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

При компиляции с параметром --enable-iouring и при поддержке ядром Linux функции io_uring futex сопрограммная блокировка модуля Swoole реализует синхронизацию через фьютекс io_uring. При такой синхронизации сопрограммы ожидают пробуждения блокировки через эффективный механизм организации очередей, который значительно повышает производительность.

Без фьютекса io_uring корутинная блокировка переключается на механизм экспоненциально нарастающего ожидания, при котором время ожидания увеличивается на 2^n миллисекунд, где n — количество отказов, после каждой неудачной попытки захватить блокировку. Хотя такой подход исключает активное ожидание, он создаёт дополнительную нагрузку на планировщик процессов и увеличивает задержки.

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

Внимание

Лучше не создавать блокировки в callback-функциях наподобие onReceive, поскольку это приведёт к неконтролируемому росту потребления памяти или даже вызовет утечки памяти.

Внимание

Захват и освобождение блокировки выполняют в той же сопрограмме, иначе нарушается логика работы программы.

Обзор класса

class Swoole\Coroutine\Lock {
/* Методы */
public function __construct (): void
public function lock (): bool
public function trylock (): bool
public function unlock (): bool
}

Примеры

Пример #1 Базовый пример работы с блокировками

<?php
use Swoole\Coroutine\Lock;
use Swoole\Coroutine\WaitGroup;
use function Swoole\Coroutine\go;
use function Swoole\Coroutine\run;
$lock = new Lock();
$waitGroup = new WaitGroup();
run(function() use ($lock, $waitGroup) {
 go(function() use ($lock, $waitGroup) {
 $waitGroup->add();
 $lock->lock();
 sleep(1);
 $lock->unlock();
 $waitGroup->done();
 });
 go(function() use ($lock, $waitGroup) {
 $waitGroup->add();
 $lock->lock(); // Дождаться, пока другая сопрограмма освободит блокировку
 sleep(1);
 $lock->unlock();
 $waitGroup->done();
 });
 echo 'Блокировка приостанавливает только текущую корутину, но не останавливает весь процесс';
 $waitGroup->wait();
});

Содержание

Нашли ошибку?

ИнструкцияИсправлениеСообщение об ошибке
+Добавить

Примечания пользователей

Пользователи ещё не добавляли примечания для страницы

AltStyle によって変換されたページ (->オリジナル) /