美文网首页PHP
PHP之Swoole 学习笔记-用做饭的方式来理解协程

PHP之Swoole 学习笔记-用做饭的方式来理解协程

作者: it阿布 | 来源:发表于2020-10-12 15:14 被阅读0次

    简介

    最近学习 swoole 接触到协程,记录一下我理解到的协程。
    文章比较白话,而且目前理解的还非常浅,写出自己的想法,请大佬们多多指点。

    协程

    协程可以简单理解为线程,只不过这个线程是用户态的,不需要操作系统参与,创建销毁和切换的成本非常低,和线程不同的是协程没法利用多核 cpu 的,想利用多核 cpu 需要依赖 Swoole 的多进程模型。—— swoole 协程一章

    我的理解

    可以把协程看成一道小学数学的一道题目:“合理安排时间”,来我们先做一道题目:

    小明下班后回家煮饭,煲汤需要 10 分钟,煮饭需要 8 分钟, 炒菜需要 5 分钟,,请问小明最少需要多少分钟能煮好饭?

    下面用 sleep() 模拟 IO 操作

    同步版煮饭

    public function async()
        {
            $startTime = time();
    
            echo "开始煲汤..." . PHP_EOL;
            sleep(10);
            echo "汤好了..." . PHP_EOL;
    
            echo "开始煮饭..." . PHP_EOL;
            sleep(8);
            echo "饭熟了..." . PHP_EOL;
    
            echo "放油..." . PHP_EOL;
            sleep(1);
            echo "煎鱼..." . PHP_EOL;
            sleep(3);
            echo "放盐..." . PHP_EOL;
            sleep(1);
            echo "出锅..." . PHP_EOL;
    
            var_dump('总耗时:' . (time() - $startTime) . ' 分钟');
        }
    

    总耗时:23 分钟

    代码很容易看懂,等待汤煮好之后再煮饭,然后再等待饭煮好再炒菜,生活中不会这样操作吧?这就要引入协程来解决这个问题了。

    协程版煮饭

    <?php
    namespace Study\Co;
    
    use Swoole\Coroutine;
    use Swoole\Coroutine\WaitGroup;
    use Swoole;
    
    class co
    {
        public function cookByCo()
        {
            $startTime = time();
    
            // 开启一键协程化: https://wiki.swoole.com/#/runtime?id=swoole_hook_all
            Swoole\Runtime::enableCoroutine($flags = SWOOLE_HOOK_ALL);
    
            // 创建一个协程容器: https://wiki.swoole.com/#/coroutine/scheduler
            // 相当于进入厨房
            \Co\run(function () {
                // 等待结果: https://wiki.swoole.com/#/coroutine/wait_group?id=waitgroup
                // 记录哪道菜做好了,哪道菜还需要多长时间
                $wg = new WaitGroup();
                // 保存数据的结果
                // 装好的菜
                $result = [];
    
                // 记录一下煲汤(记录一个任务)
                $wg->add();
                // 创建一个煲汤任务(开启一个新的协程)
                Coroutine::create(function () use ($wg, &$result) {
                    echo "开始煲汤..." . PHP_EOL;
                    // 煲汤需要6分钟,所以我们也不用在这里等汤煮好,
                    // 直接去做下一个任务:炒菜(协程切换)
                    sleep(8);
                    echo "汤好了..." . PHP_EOL;
    
                    // 装盘
                    $result['soup'] = '一锅汤';
                    $wg->done(); // 标记任务完成
                });
    
                // 记录一下煮饭(记录一个任务)
                $wg->add();
                // 创建一个煮饭任务(开启一个新的协程)
                Coroutine::create(function () use ($wg, &$result) {
                    echo "开始煮饭..." . PHP_EOL;
                    // 煮饭需要5分钟,所以我们不用在这里等饭煮熟,放在这里一会再来看看好了没有
                    // 我们先去煲汤(协程切换)
                    sleep(10);
                    echo "饭熟了..." . PHP_EOL;
    
                    // 装盘
                    $result['rice'] = '一锅米饭';
                    $wg->done(); // 标记任务完成
                });
    
                // 记录一下炒菜
                $wg->add();
                // 创建一个炒菜任务(再开启一个新的协程)
                Coroutine::create(function () use ($wg, &$result) {
                    // 煎鱼的过程必须放在一个协程里面执行,如果不是的话可能鱼还没煎好就出锅了
                    // 因为开启协程后,IO全是异步了,在此demo中每次遇到sleep都会挂起当前协程
                    // 切换到下一个协程执行。
                    // 例如把出锅这一步开启一个新协程执行,则在煎鱼的时候鱼,鱼就出锅了。
                    echo "放油..." . PHP_EOL;
                    sleep(1);
                    echo "煎鱼..." . PHP_EOL;
                    sleep(3);
                    echo "放盐..." . PHP_EOL;
                    sleep(1);
                    echo "出锅..." . PHP_EOL;
    
                    // 装盘
                    $result['food'] = '鱼香肉丝';
                    $wg->done();
                });
    
                // 等待全部任务完成
                $wg->wait();
    
                // 返回数据(上菜!)
                var_dump($result);
            });
    
            var_dump('总耗时:' . (time() - $startTime) . ' 分钟');
        }
    }
    

    总耗时:10 分钟

    答:小明最少需要 10 分钟能煮好饭。

    主要参考过的文章

    www.easyswoole.com/Cn/NoobCourse/coroutine.html
    hyperf.wiki/#/zh-cn/coroutine
    wiki.swoole.com/#/coroutine

    点关注,不迷路

    好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是人才。之前说过,PHP方面的技术点很多,也是因为太多了,实在是写不过来,写过来了大家也不会看的太多,所以我这里把它整理成了PDF和文档,如果有需要的可以

    点击进入暗号: PHP+「平台」

    在这里插入图片描述 在这里插入图片描述

    更多学习内容可以访问【对标大厂】精品PHP架构师教程目录大全,只要你能看完保证薪资上升一个台阶(持续更新)

    以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的可以加入我的 PHP技术交流群

    相关文章

      网友评论

        本文标题:PHP之Swoole 学习笔记-用做饭的方式来理解协程

        本文链接:https://www.haomeiwen.com/subject/sgaupktx.html