ThreadChannel::close
(PHP 8.6+, True Async 1.0)
php
public ThreadChannel::close(): voidCloses the channel. After closing:
- Calling
send()throws aThreadChannelException. - Calling
recv()continues to return values already in the buffer until it is drained. Once the buffer is empty,recv()throws aThreadChannelException. - Any threads currently blocked in
send()orrecv()are unblocked and receive aThreadChannelException.
Calling close() on an already closed channel is a no-op — it does not throw.
close() is the standard way to signal "end of stream" to the consuming side. The producer closes the channel after sending all items; the consumer reads until it catches ThreadChannelException.
close() itself is thread-safe and can be called from any thread.
Examples
Example #1 Producer closes after sending all items
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(); // signals: no more data
});
$consumer = spawn_thread(function() use ($channel) {
try {
while (true) {
echo $channel->recv(), "\n";
}
} catch (\Async\ThreadChannelException) {
echo "Stream ended\n";
}
});
await($producer);
await($consumer);
});Example #2 Close unblocks a waiting receiver
php
<?php
use Async\ThreadChannel;
use function Async\spawn;
use function Async\spawn_thread;
use function Async\await;
spawn(function() {
$channel = new ThreadChannel(); // unbuffered
// This thread will block in recv() waiting for a value
$waiter = spawn_thread(function() use ($channel) {
try {
$channel->recv(); // blocks
} catch (\Async\ThreadChannelException) {
return "Unblocked by close()";
}
});
// Close the channel from another thread — unblocks the waiter
spawn_thread(function() use ($channel) {
$channel->close();
});
echo await($waiter), "\n";
});Example #3 Calling close() twice is safe
php
<?php
use Async\ThreadChannel;
$channel = new ThreadChannel(5);
$channel->close();
$channel->close(); // no-op, no exception thrown
echo $channel->isClosed() ? "closed" : "open"; // "closed"See also
- ThreadChannel::isClosed — Check if the channel is closed
- ThreadChannel::recv — Receive remaining values after close
- ThreadChannel component overview