Join 4,000+ others and never miss out on new tips, tutorials, and more.
Latest version:
pecl install openswoole-22.1.2 | composer require openswoole/core:22.1.5
Channels are one of the most important concepts in Open Swoole and coroutines.
A channel is a non-blocking primitive for communication between two or more coroutines, you can use a channel to communicate between different coroutines and manage data between them.
Because coroutines have access to the same memory space, they can conflict with modifying memory which could be dependant by another coroutine as they are running within user space, on the same thread.
That is why we can solve memory access conflicts and race conditions with the help of channels. It is similar to chan
in Golang
.
You can think of a channel like a PHP array but has support for working within inside a coroutine and will not block as all operations are done within memory.
The short name \chan
is the alias of OpenSwoole\Coroutine\Channel
.
You can also use WaitGroup or batch, Barrier to sync coroutines.
OpenSwoole\Coroutine\Channel->__construct
OpenSwoole\Coroutine\Channel->push
OpenSwoole\Coroutine\Channel->pop
OpenSwoole\Coroutine\Channel->close
OpenSwoole\Coroutine\Channel->stats
OpenSwoole\Coroutine\Channel->length
OpenSwoole\Coroutine\Channel->isEmpty
OpenSwoole\Coroutine\Channel->isFull
OpenSwoole\Coroutine\Channel->getId
OpenSwoole\Coroutine\Channel->$capacity
: The queue capacity of the channel, set within the constructor when creating a new channel. Needs to be more than or equal to 1.
OpenSwoole\Coroutine\Channel->$errCode
: Get the error code status of the channel.
Return Value | Constant | Description |
---|---|---|
0 | OpenSwoole\Coroutine\Channel::CHANNEL_OK | Default success, everything is working correctly, no errors |
-1 | OpenSwoole\Coroutine\Channel::CHANNEL_TIMEOUT | Timeout when pop fails (timeout) |
-2 | OpenSwoole\Coroutine\Channel::CHANNEL_CLOSED | The channel is closed |
Here we show an example of a channel with a capacity of 1, pushing to the channel and waiting for the second coroutine to remove (pop) the data from the channel.
<?php
co::run(function () {
$chan = new OpenSwoole\Coroutine\Channel(1);
go(function() use ($chan) {
$cid = OpenSwoole\Coroutine::getCid();
$i = 0;
while (1) {
co::sleep(1);
$chan->push(['rand' => rand(1000, 9999), 'index' => $i]);
echo "[coroutine $cid] - $i\n";
$i++;
}
});
go(function() use ($chan) {
$cid = OpenSwoole\Coroutine::getCid();
while(1) {
$data = $chan->pop();
echo "[coroutine $cid]\n";
var_dump($data);
}
});
});
Below is an example which shows how a channel works in a simple manner, we create a channel and set the max capacity to 1, push the $data
to the channel and then remove (pop) from the channel to receive the data we initially put in.
Just make sure to pass your channels to each coroutine that needs access to it.
<?php
co::run(function() {
$data = 'Hello World!';
$chan = new chan(1);
$chan->push($data);
$pop = $chan->pop();
var_dump($pop);
});