• 技术文章 >php框架 >Swoole

    swoole协程的实现原理是什么

    长期闲置长期闲置2022-02-14 17:42:41原创365

    在swoole中,Swoole server接收数据在worker进程触发onReceive回调,产生一个协程,Swoole为每个请求创建对应携程,协程中也能创建子协程,协程在底层实现上是单线程的,因此同一时间只有一个协程在工作。

    本教程操作环境:Windows10系统、Swoole4版、DELL G3电脑

    swoole协程的实现原理是什么

    什么是进程?

    进程就是应用程序的启动实例。独立的文件资源,数据资源,内存空间。

    什么是线程?

    线程属于进程,是程序的执行者。一个进程至少包含一个主线程,也可以有更多的子线程。线程有两种调度策略,一是:分时调度,二是:抢占式调度。

    什么是协程?

    协程是轻量级线程,协程也是属于线程,协程是在线程里执行的。协程的调度是用户手动切换的,所以又叫用户空间线程。协程的创建、切换、挂起、销毁全部为内存操作,消耗是非常低的。协程的调度策略是:协作式调度。

    Swoole 协程的原理

    Swoole4 由于是单线程多进程的,同一时间同一个进程只会有一个协程在运行。

    Swoole server 接收数据在 worker 进程触发 onReceive 回调,产生一个携程。Swoole 为每个请求创建对应携程。协程中也能创建子协程。

    协程在底层实现上是单线程的,因此同一时间只有一个协程在工作,协程的执行是串行的。

    因此多任务多协程执行时,一个协程正在运行时,其他协程会停止工作。当前协程执行阻塞 IO 操作时会挂起,底层调度器会进入事件循环。当有 IO 完成事件时,底层调度器恢复事件对应的协程的执行。。所以协程不存在 IO 耗时,非常适合高并发 IO 场景。(如下图)

    18.png

    Swoole 的协程执行流程

    协程的执行顺序

    先来看看基础的例子:

    go(function () {
        echo "hello go1 \n";});echo "hello main \n";go(function () {
        echo "hello go2 \n";});

    go() 是 \Co::create() 的缩写, 用来创建一个协程, 接受 callback 作为参数, callback 中的代码, 会在这个新建的协程中执行.

    备注: \Swoole\Coroutine 可以简写为 \Co

    上面的代码执行结果:

    root@b98940b00a9b /v/w/c/p/swoole# php co.phphello go1
    hello main
    hello go2

    执行结果和我们平时写代码的顺序, 好像没啥区别. 实际执行过程:

    运行此段代码, 系统启动一个新进程. 如果不理解这句话, 你可以使用如下代码:

    // co.php<?phpsleep(100);

    执行并使用 ps aux 查看系统中的进程:

    root@b98940b00a9b /v/w/c/p/swoole# php co.php &⏎
    root@b98940b00a9b /v/w/c/p/swoole# ps auxPID   USER     TIME   COMMAND
        1 root       0:00 php -a   10 root       0:00 sh   19 root       0:01 fish  749 root       0:00 php co.php  760 root       0:00 ps aux

    我们来稍微改一改, 体验协程的调度:

    use Co;go(function () {
        Co::sleep(1); // 只新增了一行代码
        echo "hello go1 \n";});echo "hello main \n";go(function () {
        echo "hello go2 \n";});
    \Co::sleep() 函数功能和 sleep() 差不多, 但是它模拟的是 IO等待(IO后面会细讲). 执行的结果如下:
    root@b98940b00a9b /v/w/c/p/swoole# php co.phphello main
    hello go2
    hello go1

    怎么不是顺序执行的呢? 实际执行过程:

    到这里, 已经可以看到 swoole 中 协程与进程的关系, 以及 协程的调度, 我们再改一改刚才的程序:

    go(function () {
        Co::sleep(1);
        echo "hello go1 \n";});echo "hello main \n";go(function () {
        Co::sleep(1);
        echo "hello go2 \n";});

    我想你已经知道输出是什么样子了:

    root@b98940b00a9b /v/w/c/p/swoole# php co.phphello main
    hello go1
    hello go2

    推荐学习: swoole教程

    以上就是swoole协程的实现原理是什么的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:swoole
    上一篇:swoole怎么实现定时任务 下一篇:利用 webSocket 与 Swoole 打造一个小型聊天室(协程)
    PHP编程就业班

    相关文章推荐

    • 什么是swoole框架• swoole是干什么的• go语言和swoole的区别是什么• swoole协程和go协程的区别是什么• swoole进程与线程有什么区别

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网