• Coroutine\Channel
    • 方法
    • 属性
    • 示例
    • 连接池

    Coroutine\Channel

    通道,类似于go语言的chan,支持多生产者协程和多消费者协程。底层自动实现了协程的切换和调度。通道与PHPArray类似,仅占用内存,没有其他额外的资源申请,所有操作均为内存操作,无IO消耗。

    方法

    • Channel->push :当队列中有其他协程正在等待pop数据时,自动按顺序唤醒一个消费者协程。当队列已满时自动yield让出控制器,等待其他协程消费数据
    • Channel->pop:当队列为空时自动yield,等待其他协程生产数据。消费数据后,队列可写入新的数据,自动按顺序唤醒一个生产者协程。
    Coroutine\Channel使用本地内存,不同的进程之间内存是隔离的。只能在同一进程的不同协程内进行pushpop操作 Coroutine\Channel2.0.13或更高版本可用

    属性

    • $capacity 通道缓冲区容量
    • $errCode channel错误码

    示例

    1. use Swoole\Coroutine as co;
    2. $chan = new co\Channel(1);
    3. co::create(function () use ($chan) {
    4. for($i = 0; $i < 100000; $i++) {
    5. co::sleep(1.0);
    6. $chan->push(['rand' => rand(1000, 9999), 'index' => $i]);
    7. echo "$i\n";
    8. }
    9. });
    10. co::create(function () use ($chan) {
    11. while(1) {
    12. $data = $chan->pop();
    13. var_dump($data);
    14. }
    15. });
    16. swoole_event::wait();

    连接池

    使用 Chan 可以方便得实现连接池功能。管理各类 Socket 连接资源。

    1. class RedisPool
    2. {
    3. /**
    4. * @var \Swoole\Coroutine\Channel
    5. */
    6. protected $pool;
    7. /**
    8. * RedisPool constructor.
    9. * @param int $size 连接池的尺寸
    10. */
    11. function __construct($size = 100)
    12. {
    13. $this->pool = new Swoole\Coroutine\Channel($size);
    14. for ($i = 0; $i < $size; $i++)
    15. {
    16. $redis = new Swoole\Coroutine\Redis();
    17. $res = $redis->connect('127.0.0.1', 6379);
    18. if ($res == false)
    19. {
    20. throw new RuntimeException("failed to connect redis server.");
    21. }
    22. else
    23. {
    24. $this->put($redis);
    25. }
    26. }
    27. }
    28. function put($redis)
    29. {
    30. $this->pool->push($redis);
    31. }
    32. function get()
    33. {
    34. return $this->pool->pop();
    35. }
    36. }