Coroutine\Channel

最后更新于:2022-04-02 06:26:29

# Coroutine\\Channel [TOC] 通道,类似于`go`语言的`chan`,支持多生产者协程和多消费者协程。底层自动实现了协程的切换和调度。 通道与`PHP`的`Array`类似,仅占用内存,没有其他额外的资源申请,所有操作均为内存操作,无`IO`消耗。 ## 方法 * `Channel->push`:当队列中有其他协程正在等待`pop`数据时,自动按顺序唤醒一个消费者协程。当队列已满时自动`yield`让出控制器,等待其他协程消费数据 * `Channel->pop`:当队列为空时自动`yield`,等待其他协程生产数据。消费数据后,队列可写入新的数据,自动按顺序唤醒一个生产者协程。 > `Coroutine\Channel`使用本地内存,不同的进程之间内存是隔离的。只能在同一进程的不同协程内进行`push`和`pop`操作 > `Coroutine\Channel`在`2.0.13`或更高版本可用 ## 属性 * `$capacity`通道缓冲区容量 * `$errCode`channel错误码 ## 示例 ~~~ use Swoole\Coroutine as co; $chan = new co\Channel(1); co::create(function () use ($chan) { for($i = 0; $i < 100000; $i++) { co::sleep(1.0); $chan->push(['rand' => rand(1000, 9999), 'index' => $i]); echo "$i\n"; } }); co::create(function () use ($chan) { while(1) { $data = $chan->pop(); var_dump($data); } }); swoole_event::wait(); ~~~ ## 连接池 使用`Chan`可以方便得实现连接池功能。管理各类`Socket`连接资源。 ~~~ class RedisPool { /** * @var \Swoole\Coroutine\Channel */ protected $pool; /** * RedisPool constructor. * @param int $size 连接池的尺寸 */ function __construct($size = 100) { $this->pool = new Swoole\Coroutine\Channel($size); for ($i = 0; $i < $size; $i++) { $redis = new Swoole\Coroutine\Redis(); $res = $redis->connect('127.0.0.1', 6379); if ($res == false) { throw new RuntimeException("failed to connect redis server."); } else { $this->put($redis); } } } function put($redis) { $this->pool->push($redis); } function get() { return $this->pool->pop(); } } ~~~
';