Coroutine\Channel::select
最后更新于:2022-04-02 06:42:59
# Coroutine\\Channel::select
[TOC]
## 废弃
~~~
此方法存在安全问题,已废弃
~~~
通道读写检测。类似于`socket_select`和`stream_select`可以检测`channel`是否可进行读写。
## 原型
~~~
function Coroutine\Channel::select(array &$read, array &$write, float $timeout = -1);
~~~
当`$read`或`$write`数组中有部分`channel`对象处于可读或可写状态,`select`会立即返回,不会产生协程调度。当数组中没有任何`channel`可读或可写时,将挂起当前协程,并设置定时器。当其中一个通道可读或可写时,将重新唤醒当前协程。
`select`操作只检测`channel`列表的可读或可写状态,但并不会读写`channel`,在`select`调用返回后,可遍历`$read`和`$write`数组,执行`pop`和`push`方法,完成通道读写操作。
## 参数
* `$read`数组引用类型,元素为`channel`对象,读操作检测,可以为`null`
* `$write`数组引用类型,元素为`channel`对象,写操作检测,可以为`null`
* `$timeout`浮点型,超时设置,单位为秒,最小粒度为`0.001`秒,即`1ms`。默认为`0`,表示永不超时。
## 返回值
* 成功返回`true`,底层会修改`$read`、`$write`数组,`$read`和`$write`中的元素,即是可读或可写的`channel`
* 超时或传入的参数错误,如`$read`和`$write`中有非`channel`对象,底层返回`false`
## 注意事项
早期版本中`Coroutine\Channel`由于存在一些问题,在`Swoole4.0.3`版本重构并废弃了`Coroutine\Channel::select`方法。所以在`Swoole4.0.3`以上的版本请使用`channel->pop($timeout)`替代。
## fibonacci 实例
~~~
$c1 = new chan();
$c2 = new chan();
function fibonacci($c1, $c2)
{
go(function () use ($c1, $c2) {
$a = 0;
$b = 1;
while(1) {
$read_list = [$c2];
$write_list = [$c1];
$result = chan::select($read_list, $write_list, 2);
if ($write_list) {
$t = $a + $b;
$a = $b;
$b = $t;
$c1->push($a);
}
if ($read_list) {
$ret = $c2->pop();
if ($ret === 1) {
return 1;
}
}
}
});
}
$num = 10;
go(function () use ($c1, $c2, $num) {
for ($i = 0; $i < $num; $i ++) {
$ret = $c1->pop();
echo "fibonacci @$i $ret\n";
}
$c2->push(1);
});
fibonacci($c1, $c2);
~~~
';