关于协程的优点以及swoole 协程的用法

举报
仙士可 发表于 2023/06/21 16:37:08 2023/06/21
【摘要】 在上篇文章中php yield关键字以及协程的实现  我们讲到了协程的原理以及运行步骤.现在我们来继续看下协程的执行顺序.协程的运行是交叉式运行(串行),只要你发起了一次协程切换,则会立马暂停当前协程,去运行下一个协程,直到下次代码调度回协程.协程的优点看到上面的执行顺序,你可能还是不能理解协程的优点,这个其实是一个很简单的概念,举个例子:小明烧开水需要10分钟,刷牙需要3分钟,吃早餐需要5...

在上篇文章中php yield关键字以及协程的实现  我们讲到了协程的原理以及运行步骤.

现在我们来继续看下协程的执行顺序.

协程的运行是交叉式运行(串行),只要你发起了一次协程切换,则会立马暂停当前协程,去运行下一个协程,直到下次代码调度回协程.

协程的优点

看到上面的执行顺序,你可能还是不能理解协程的优点,这个其实是一个很简单的概念,举个例子:

小明烧开水需要10分钟,刷牙需要3分钟,吃早餐需要5分钟,请问做完这些事情总共需要多少分钟?

答案是10分钟,因为在烧开水这个步骤时,不需要坐在那里看水壶烧(异步,io耗时)可以先去刷牙,然后去吃早餐

协程的优点主要在于这里,当遇上io耗时的情况时,这部分的等待时间我们其实可以节约出来,去先处理其他代码逻辑的,直到io完成再继续执行之前的代码.

没错,协程的优点就在于这个.

swoole协程

在swoole中,已经自带了协程管理器,以及异步io的扩展(redis.mysql,http客户端等),我们只要安装好swoole扩展,就可以直接使用协程了,例如以下代码:

$start_time = time();
/*for ($i = 0; $i <= 500; $i++) {
    go(function ()use($i,$start_time){
        $cli = new Swoole\Coroutine\Http\Client('www.baidu.com', 443,true);
        $cli->setHeaders([
            'Host' => "www.baidu.com",
            "User-Agent" => 'Chrome/49.0.2587.3',
            'Accept' => 'text/html,application/xhtml+xml,application/xml',
            'Accept-Encoding' => 'gzip',
        ]);
        $cli->set([ 'timeout' => 0.11]);
        $cli->get('/');
        $cli->close();
        echo  "协程{$i}已完成,耗时".(time()-$start_time).PHP_EOL;
    });
}*/
$start_time = time();
for ($i = 0; $i <= 500; $i++) {
    $url     = 'https://www.baidu.com/';
    $content = file_get_contents($url);
    echo "普通{$i}已完成\n";
}
echo "非携程完成时间:" . (time() - $start_time);
复制

在非协程环境,它的执行顺序和执行时间如下:

而在注释掉非协程代码,协程环境运行下,它的执行顺序和时间如下:

为什么会这样呢?我说下具体的流程:

非协程流程

1:先执行$i=0

2:通过file_get_contents获取网页内容

3:获取成功后在进行输出: 普通0已完成

4:继续执行$i=1

...

协程流程

1:先执行$i=0

2:通过异步client类,去请求https://www.baidu.com

3:协程切换不等待获取网页内容,直接跳到$i=1

4:通过异步client类,去请求https://www.baidu.com

....

n:$i=0的请求内容已经完成,切换回$i=0后面的代码,输出"协程0已完成,耗时0"

n+1:通过异步client类,去请求https://www.baidu.com,协程切换不等待获取网页内容,直接跳到$i=n+2

n+2:$i=n的请求内容已经完成,切换回$i=n后面的代码,输出"协程n已完成,耗时5"

....

由这2个流程可以看出一个不同之处:非协程需要等待请求网页的时间,而协程直接跳过了等待的时间,继续往下执行,

也就是上面说的"小明烧开水的时间先去刷牙"

然后,由于协程没有了io耗时,执行速度大大提高,假设请求一次网站需要0.05秒,那500次循环就相当于节省了25秒,这就是为什么协程适合在高并发io场景的原因了

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。