ThreadChannel::close
(PHP 8.6+, True Async 1.0)
php
public ThreadChannel::close(): voidЗакриває канал. Після закриття:
- Виклик
send()кидаєThreadChannelException. - Виклик
recv()продовжує повертати значення, що вже знаходяться в буфері, поки він не буде спустошений. Як тільки буфер порожній,recv()кидаєThreadChannelException. - Будь-які потоки, заблоковані в
send()абоrecv(), розблоковуються і отримуютьThreadChannelException.
Виклик close() на вже закритому каналі є порожньою операцією — він не кидає виняток.
close() — це стандартний спосіб сигналізувати «кінець потоку» для сторони-споживача. Виробник закриває канал після надсилання всіх елементів; споживач читає до тих пір, поки не перехопить ThreadChannelException.
close() є потокобезпечним і може бути викликаний із будь-якого потоку.
Приклади
Приклад #1 Виробник закриває канал після надсилання всіх елементів
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(); // сигнал: більше даних немає
});
$consumer = spawn_thread(function() use ($channel) {
try {
while (true) {
echo $channel->recv(), "\n";
}
} catch (\Async\ThreadChannelException) {
echo "Stream ended\n";
}
});
await($producer);
await($consumer);
});Приклад #2 Close розблоковує очікуючого отримувача
php
<?php
use Async\ThreadChannel;
use function Async\spawn;
use function Async\spawn_thread;
use function Async\await;
spawn(function() {
$channel = new ThreadChannel(); // небуферизований
// Цей потік блокуватиметься в recv(), очікуючи значення
$waiter = spawn_thread(function() use ($channel) {
try {
$channel->recv(); // блокує
} catch (\Async\ThreadChannelException) {
return "Unblocked by close()";
}
});
// Закриваємо канал з іншого потоку — розблоковує очікувача
spawn_thread(function() use ($channel) {
$channel->close();
});
echo await($waiter), "\n";
});Приклад #3 Подвійний виклик close() є безпечним
php
<?php
use Async\ThreadChannel;
$channel = new ThreadChannel(5);
$channel->close();
$channel->close(); // порожня операція, виняток не кидається
echo $channel->isClosed() ? "closed" : "open"; // "closed"Дивіться також
- ThreadChannel::isClosed — Перевірити, чи закритий канал
- ThreadChannel::recv — Отримати значення, що залишились після закриття
- Огляд компонента ThreadChannel