ThreadChannel::__construct
(PHP 8.6+, True Async 1.0)
public ThreadChannel::__construct(int $capacity = 0)Создаёт новый потокобезопасный канал для передачи данных между потоками ОС.
ThreadChannel — это межпоточный аналог Channel. Если Channel предназначен для взаимодействия корутин внутри одного потока, то ThreadChannel позволяет безопасно передавать данные между отдельными потоками ОС — например, между главным потоком и рабочим, запущенным через spawn_thread() или переданным в ThreadPool.
Поведение канала определяется параметром $capacity:
capacity = 0— небуферизованный (синхронный) канал.send()блокирует вызывающий поток до тех пор, пока другой поток не вызоветrecv(). Это гарантирует, что получатель готов принять данные до того, как отправитель продолжит работу.capacity > 0— буферизованный канал.send()не блокируется, пока в буфере есть место. Когда буфер заполнен, вызывающий поток блокируется до освобождения места.
Все значения, передаваемые через канал, глубоко копируются — применяются те же правила сериализации, что и при spawn_thread(). Объекты, которые не поддаются сериализации (например, замыкания, ресурсы, stdClass со ссылками), вызывают ThreadTransferException.
Параметры
capacity : Ёмкость внутреннего буфера канала. 0 — небуферизованный канал (по умолчанию), send() блокируется до готовности получателя. Положительное число — размер буфера; send() блокируется только при заполненном буфере.
Примеры
Пример #1 Небуферизованный канал между потоками
<?php
use Async\ThreadChannel;
use function Async\spawn;
use function Async\spawn_thread;
use function Async\await;
spawn(function() {
$channel = new ThreadChannel(); // capacity = 0
$thread = spawn_thread(function() use ($channel) {
$value = $channel->recv(); // блокируется до отправки из главного потока
return "Worker received: $value";
});
$channel->send('hello'); // блокируется до вызова recv() в рабочем потоке
echo await($thread), "\n";
});Пример #2 Буферизованный канал между потоками
<?php
use Async\ThreadChannel;
use function Async\spawn;
use function Async\spawn_thread;
use function Async\await;
spawn(function() {
$channel = new ThreadChannel(10); // буфер на 10 элементов
$producer = spawn_thread(function() use ($channel) {
for ($i = 1; $i <= 10; $i++) {
$channel->send($i); // не блокируется, пока буфер не заполнен
}
$channel->close();
});
$consumer = spawn_thread(function() use ($channel) {
$results = [];
while (!$channel->isClosed() || !$channel->isEmpty()) {
try {
$results[] = $channel->recv();
} catch (\Async\ThreadChannelException) {
break;
}
}
return $results;
});
await($producer);
$results = await($consumer);
echo implode(', ', $results), "\n";
});Смотрите также
- ThreadChannel::send — Отправить значение в канал
- ThreadChannel::recv — Получить значение из канала
- ThreadChannel::capacity — Получить ёмкость канала
- ThreadChannel::close — Закрыть канал
- Обзор компонента ThreadChannel