ComponentesThreadChannel::close()

ThreadChannel::close

(PHP 8.6+, True Async 1.0)

php
public ThreadChannel::close(): void

Cierra el canal. Después del cierre:

  • Llamar a send() lanza una ThreadChannelException.
  • Llamar a recv() continúa devolviendo los valores ya presentes en el buffer hasta que se vacíe. Una vez que el buffer esté vacío, recv() lanza una ThreadChannelException.
  • Los hilos actualmente bloqueados en send() o recv() son desbloqueados y reciben una ThreadChannelException.

Llamar a close() en un canal ya cerrado no hace nada — no lanza ninguna excepción.

close() es la forma estándar de señalar "fin de flujo" al lado consumidor. El productor cierra el canal después de enviar todos los elementos; el consumidor lee hasta que captura ThreadChannelException.

close() en sí mismo es seguro para hilos y puede ser llamado desde cualquier hilo.

Ejemplos

Ejemplo #1 El productor cierra tras enviar todos los elementos

php
<?php

use Async\ThreadChannel;
use function Async\spawn;
use function Async\spawn_thread;
use function Async\await;

spawn(function() {
    $channel = new ThreadChannel(10);

    $producer = spawn_thread(function() use ($channel) {
        foreach (['alpha', 'beta', 'gamma'] as $item) {
            $channel->send($item);
        }
        $channel->close(); // señala: no hay más datos
    });

    $consumer = spawn_thread(function() use ($channel) {
        try {
            while (true) {
                echo $channel->recv(), "\n";
            }
        } catch (\Async\ThreadChannelException) {
            echo "Flujo terminado\n";
        }
    });

    await($producer);
    await($consumer);
});

Ejemplo #2 Close desbloquea a un receptor en espera

php
<?php

use Async\ThreadChannel;
use function Async\spawn;
use function Async\spawn_thread;
use function Async\await;

spawn(function() {
    $channel = new ThreadChannel(); // sin buffer

    // Este hilo se bloqueará en recv() esperando un valor
    $waiter = spawn_thread(function() use ($channel) {
        try {
            $channel->recv(); // bloquea
        } catch (\Async\ThreadChannelException) {
            return "Desbloqueado por close()";
        }
    });

    // Cerrar el canal desde otro hilo — desbloquea al que espera
    spawn_thread(function() use ($channel) {
        $channel->close();
    });

    echo await($waiter), "\n";
});

Ejemplo #3 Llamar a close() dos veces es seguro

php
<?php

use Async\ThreadChannel;

$channel = new ThreadChannel(5);
$channel->close();
$channel->close(); // no hace nada, no lanza excepción

echo $channel->isClosed() ? "cerrado" : "abierto"; // "cerrado"

Véase también