swoole之协程channel元素个数

栏目: PHP · 发布时间: 5年前

内容简介:channel用于进程内跨协程通讯,按照角色分为生产协程和消费协程。生产协程,在channel已满时,会被挂起;消费协程,在channel为空是,也会被挂起。

前言

channel用于进程内跨协程通讯,按照角色分为生产协程和消费协程。

生产协程,在channel已满时,会被挂起;

消费协程,在channel为空是,也会被挂起。

看例子

<?php
$chan = new \Swoole\Coroutine\Channel(50);
function t4(\Swoole\Coroutine\Channel $chan)
{
    Co::sleep(0.005);
    $chan->push([__METHOD__ => __LINE__]);
}
function t5(\Swoole\Coroutine\Channel $chan)
{
    Co::sleep(0.005);
    $chan->push([__METHOD__ => __LINE__]);
}
go("t4", $chan);
go("t5", $chan);

go(function () use ($chan) {
    // chan元素个数
    $chanNum = 1;
    while ($chanNum > 0) {
        $item = $chan->pop();
        var_dump($item);
        $chanNum--;
    }
});

分析

上面的例子,如果赋值$chanNum=1,会导致channel中有数据未被消费;

如果赋值$chanNum=3,由于channel数据不足,消费协程会挂起,程序无法正常退出。

准确设置channel元素个数,是很重要的事。

实践中,有些场景无法预测channel元素个数(例如请求第三方接口,如果有数据则push到channel,无数据则不push),那有什么解决办法嘛?

有!

保证生产者协程不挂起的前提下,在 php 的register_shutdown_function()函数中,去实现未完成的消费者功能

<?php
register_shutdown_function(function() use ($chan) {
    go(function()use($chan){
        $queue_num = $chan->stats()["queue_num"];
        for($i=0;$i<$queue_num;$i++) {
            var_dump($chan->pop());
        }
    });
});

这个办法能解决问题,但是显然不是那么优雅

消费者函数要重复写一遍,由于swoole协程的语法,无法复用这个问题,应该在swoole协程层面来处理,在register_shutdown_function()中处理,也只是临时解决办法

总结

swoole协程的push/pop机制,决定了需要设置一个合理的channel元素个数。

实践中某些场景,又无法准确评估这个值,只能用临时办法解决,希望swoole能提供更优雅的解决方式。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

创新者的处方

创新者的处方

[美]克莱顿·克里斯坦森、杰罗姆·格罗斯曼、黄捷升 / 朱恒鹏、张琦 / 中国人民大学出版社 / 2015-9 / 89.90元

[内容简介] ● 创新大师克里斯坦森采用了哈佛商学院在20年研究中总结而出的、在各行业实践中获得成功的管理创新经验,把颠覆式创新理念引入美国医疗行业研究。医疗机构需要量体裁衣,选择合适的商业模式展开创新之举。 ● 作者同时探讨了医疗保险公司、制药企业、医学院和政府机构在医疗改革中起到的作用,从社会性角度深入剖析了医疗保健行业未来之路。 ● 医疗界人士、政策制定者、对医疗界现......一起来看看 《创新者的处方》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换