КомпонентыThreadPool::cancel()

ThreadPool::cancel()

(PHP 8.6+, True Async 1.0)

php
public ThreadPool::cancel(): void

Инициирует принудительное завершение работы пула. После вызова cancel():

  • Любой последующий вызов submit() немедленно выбрасывает Async\ThreadPoolException.
  • Задачи, ожидающие в очереди (ещё не взятые рабочим потоком), немедленно отклоняются — соответствующие объекты Future переходят в состояние отклонения с ThreadPoolException (а в режиме coroutine: true — с CancellationException).
  • В обычном режиме (coroutine: false) задачи, уже выполняющиеся в рабочих потоках, доводятся до конца текущей задачи — принудительное прерывание PHP-кода в OS-потоке невозможно.
  • В режиме coroutine: true in-flight задачи реально кэнселятся (начиная с TrueAsync 0.7.0): атомарный флаг cancel_requested выставляется до закрытия канала, воркер вызывает ZEND_ASYNC_SCOPE_CANCEL(pool_scope, NULL, false, false), и AFTER_MAIN каскадно отменяет все child-scope'ы запущенных задач.
  • Рабочие потоки останавливаются сразу после завершения текущей задачи и не берут новые задачи из очереди.

Для мягкого завершения, при котором все задачи в очереди доводятся до конца, используйте close().

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

void

Примеры

Пример #1 Принудительная отмена при наличии задач в очереди

php
<?php

use Async\ThreadPool;
use Async\ThreadPoolException;
use function Async\spawn;
use function Async\await;

spawn(function() {
    $pool = new ThreadPool(workers: 2, queueSize: 10);

    // Заполняем очередь 8 задачами на 2 рабочих потока
    $futures = [];
    for ($i = 0; $i < 8; $i++) {
        $futures[] = $pool->submit(function() use ($i) {
            $t = microtime(true);
            while (microtime(true) - $t < 0.2) {}
            return $i;
        });
    }

    // Немедленная отмена — задачи в очереди отклоняются
    $pool->cancel();

    $done = 0;
    $cancelled = 0;
    foreach ($futures as $f) {
        try {
            await($f);
            $done++;
        } catch (ThreadPoolException $e) {
            $cancelled++;
        }
    }

    echo "done:      $done\n";      // 2  (уже выполнялись на момент вызова cancel())
    echo "cancelled: $cancelled\n"; // 6  (ещё находились в очереди)
});

Смотрите также