suspend

(PHP 8.6+, True Async 1.0)

suspend() — Приостанавливает выполнение текущей корутины

Описание

suspend: void

Приостанавливает выполнение текущей корутины и передаёт управление планировщику. Выполнение корутины будет возобновлено позже, когда планировщик решит её запустить.

suspend() — функция, предоставляемая расширением True Async.

Параметры

Эта конструкция не имеет параметров.

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

Функция не возвращает значения.

Примеры

Пример #1 Базовое использование suspend

<?php
use function Async\spawn;

spawn(function() {
    echo "До suspend\n";
    suspend();
    echo "После suspend\n";
});

echo "Основной код\n";
?>

Результат:

До suspend
Основной код
После suspend

Пример #2 Множественные suspend

<?php
use function Async\spawn;

spawn(function() {
    for ($i = 1; $i <= 3; $i++) {
        echo "Итерация $i\n";
        suspend();
    }
});

echo "Корутина запущена\n";
?>

Результат:

Итерация 1
Корутина запущена
Итерация 2
Итерация 3

Пример #3 Кооперативная многозадачность

<?php
use function Async\spawn;

spawn(function() {
    for ($i = 1; $i <= 5; $i++) {
        echo "Корутина A: $i\n";
        suspend(); // Даём другим корутинам шанс выполниться
    }
});

spawn(function() {
    for ($i = 1; $i <= 5; $i++) {
        echo "Корутина B: $i\n";
        suspend();
    }
});
?>

Результат:

Корутина A: 1
Корутина B: 1
Корутина A: 2
Корутина B: 2
Корутина A: 3
Корутина B: 3
...

Пример #4 Явная уступка управления

<?php
use function Async\spawn;

spawn(function() {
    echo "Начинаю долгую работу\n";

    for ($i = 0; $i < 1000000; $i++) {
        // Вычисления

        if ($i % 100000 === 0) {
            suspend(); // Периодически уступаем управление
        }
    }

    echo "Работа завершена\n";
});

spawn(function() {
    echo "Другая корутина тоже работает\n";
});
?>

Пример #5 suspend из вложенных функций

suspend() работает из любой глубины вызова — не обязательно вызывать напрямую из корутины:

<?php
use function Async\spawn;

function nestedSuspend() {
    echo "Вложенная функция: до suspend\n";
    suspend();
    echo "Вложенная функция: после suspend\n";
}

function deeplyNested() {
    echo "Глубокий вызов: начало\n";
    nestedSuspend();
    echo "Глубокий вызов: конец\n";
}

spawn(function() {
    echo "Корутина: до вложенного вызова\n";
    deeplyNested();
    echo "Корутина: после вложенного вызова\n";
});

spawn(function() {
    echo "Другая корутина: работаю\n";
});
?>

Результат:

Корутина: до вложенного вызова
Глубокий вызов: начало
Вложенная функция: до suspend
Другая корутина: работаю
Вложенная функция: после suspend
Глубокий вызов: конец
Корутина: после вложенного вызова

Пример #6 suspend в цикле ожидания

<?php
use function Async\spawn;

$ready = false;

spawn(function() use (&$ready) {
    // Ждём, пока флаг не станет true
    while (!$ready) {
        suspend(); // Уступаем управление
    }

    echo "Условие выполнено!\n";
});

spawn(function() use (&$ready) {
    echo "Подготовка...\n";
    Async\sleep(2000);
    $ready = true;
    echo "Готово!\n";
});
?>

Результат:

Подготовка...
Готово!
Условие выполнено!

Примечания

Примечание: suspend() — функция. Вызывать её как suspend (без скобок) неправильно.

Примечание: В TrueAsync весь выполняемый код рассматривается как корутина, поэтому suspend() можно вызывать в любом месте (включая основной скрипт).

Примечание: После вызова suspend() выполнение корутины возобновится не сразу, а когда планировщик решит её запустить. Порядок возобновления корутин не гарантируется.

Примечание: В большинстве случаев явное использование suspend() не требуется. Корутины автоматически приостанавливаются при выполнении I/O операций (чтение файлов, сетевые запросы и т.д.).

Примечание: Использование suspend() в бесконечных циклах без I/O операций может привести к высокой нагрузке на CPU. Вы так же можете использовать Async\timeout().

Changelog

Версия Описание
1.0.0 Добавлена функция suspend()

См. также