signal

(PHP 8.6+, True Async 1.0)

signal() — Ожидает получение OS-сигнала. Возвращает Future, который разрешается значением Signal при получении сигнала.

Описание

php
signal(Async\Signal $signal, ?Async\Completable $cancellation = null): Async\Future

Создаёт одноразовый обработчик OS-сигнала. Каждый вызов signal() создаёт новый Future, который разрешается при первом получении указанного сигнала. Если передан параметр $cancellation, Future будет отклонён при срабатывании отмены (например, по таймауту).

Несколько вызовов signal() с одним и тем же сигналом работают независимо — каждый получит уведомление.

Параметры

signal Значение перечисления Async\Signal, определяющее ожидаемый сигнал. Например: Signal::SIGINT, Signal::SIGTERM, Signal::SIGUSR1.

cancellation Опциональный объект, реализующий Async\Completable (например, результат вызова timeout()). Если объект отмены срабатывает раньше, чем придёт сигнал, Future будет отклонён с соответствующим исключением (например, Async\TimeoutException).

Если объект отмены уже завершён на момент вызова, signal() немедленно возвращает отклонённый Future.

Возвращаемое значение

Возвращает Async\Future<Async\Signal>. При получении сигнала Future разрешается значением перечисления Async\Signal, соответствующим полученному сигналу.

Ошибки/Исключения

  • Async\OperationCanceledException — если сработал токен отмены (включая таймаут). Оригинальное исключение из токена доступно через $e->getPrevious() (например, TimeoutException при использовании timeout()).

Примеры

Пример #1 Ожидание сигнала с таймаутом

php
<?php
use Async\Signal;
use function Async\signal;
use function Async\timeout;
use function Async\await;

try {
    $result = await(signal(Signal::SIGINT, timeout(5000)));
    echo "Получен сигнал: " . $result->name . "\n";
} catch (Async\OperationCanceledException $e) {
    echo "Сигнал не получен за 5 секунд\n";
}
?>

Пример #2 Получение сигнала из другой корутины

php
<?php
use Async\Signal;
use function Async\signal;
use function Async\await;
use function Async\spawn;

$future = signal(Signal::SIGUSR1);

spawn(function() {
    posix_kill(getmypid(), SIGUSR1);
});

$result = await($future);
echo "Получен сигнал: " . $result->name . "\n";
var_dump($result === Signal::SIGUSR1); // bool(true)
?>

Пример #3 Graceful shutdown по SIGTERM

php
<?php
use Async\Signal;
use function Async\signal;
use function Async\await;
use function Async\spawn;
use function Async\graceful_shutdown;

spawn(function() {
    await(signal(Signal::SIGTERM));
    echo "SIGTERM получен, завершаемся...\n";
    graceful_shutdown();
});
?>

Пример #4 Уже истёкший таймаут

php
<?php
use Async\Signal;
use function Async\signal;
use function Async\timeout;
use function Async\await;
use function Async\delay;

$t = timeout(1);
delay(50); // Таймаут уже истёк

$future = signal(Signal::SIGINT, $t);

try {
    await($future);
} catch (Async\OperationCanceledException $e) {
    echo get_class($e) . "\n"; // Async\OperationCanceledException
    echo get_class($e->getPrevious()) . "\n"; // Async\TimeoutException
}
?>

Примечания

Примечание: Каждый вызов signal() создаёт одноразовый обработчик. Для повторного ожидания того же сигнала вызовите signal() снова.

Примечание: Signal::SIGINT и Signal::SIGBREAK работают на всех платформах, включая Windows. Сигналы SIGUSR1, SIGUSR2 и другие POSIX-сигналы доступны только на Unix-системах.

Примечание: Signal::SIGKILL и Signal::SIGSEGV не могут быть перехвачены — это ограничение операционной системы.

Signal

Перечисление Async\Signal определяет доступные OS-сигналы:

ЗначениеСигналОписание
Signal::SIGHUP1Потеря связи с терминалом
Signal::SIGINT2Прерывание (Ctrl+C)
Signal::SIGQUIT3Выход с дампом ядра
Signal::SIGILL4Недопустимая инструкция
Signal::SIGABRT6Аварийное завершение
Signal::SIGFPE8Ошибка арифметики с плавающей точкой
Signal::SIGKILL9Безусловное завершение
Signal::SIGUSR110Пользовательский сигнал 1
Signal::SIGSEGV11Нарушение доступа к памяти
Signal::SIGUSR212Пользовательский сигнал 2
Signal::SIGTERM15Запрос на завершение
Signal::SIGBREAK21Прерывание (Ctrl+Break, Windows)
Signal::SIGABRT222Аварийное завершение (альтернативный)
Signal::SIGWINCH28Изменение размера окна терминала

См. также

  • timeout() — создание таймаута для ограничения ожидания
  • await() — ожидание результата Future
  • graceful_shutdown() — корректное завершение планировщика
  • Отмена — механизм отмены