zoukankan      html  css  js  c++  java
  • Swoole从入门到入土(27)——协程[协程容器]

    这一章开始,我们要开始全方位讨论Swoole为我们提供的协程机制。在swoole中所有的协程必须在协程容器里面创建(SwooleCoroutineScheduler),Swoole 程序启动的时候大部分情况会自动创建协程容器,用 Swoole 启动程序的方式一共有三种:

    - 调用异步风格服务端程序的 start 方法,此种启动方式会在事件回调中创建协程容器,参考 enable_coroutine。

    - 调用 Swoole 提供的 2 个进程管理模块 Process 和 ProcessPool 的 start 方法,此种启动方式会在进程启动的时候创建协程容器,参考这两个模块构造函数的 enable_coroutine 参数。

    - 其他直接裸写协程的方式启动程序,需要先创建一个协程容器 (Co un() 函数,可以理解为 java、c 的 main 函数)。

    示例1:启动一个全协程的HTTP服务器

    Co
    un(function () {
        $server = new CoHttpServer("127.0.0.1", 9502, false);
        $server->handle('/', function ($request, $response) {
            $response->end("<h1>Index</h1>");
        });
        $server->handle('/test', function ($request, $response) {
            $response->end("<h1>Test</h1>");
        });
        $server->handle('/stop', function ($request, $response) use ($server) {
            $response->end("<h1>Stop</h1>");
            $server->shutdown();
        });
        $server->start();
    });
    echo 1;//得不到执行

    示例2:添加2个并发协程

    Co
    un(function () {
        go(function() {
            var_dump(file_get_contents("http://www.xinhuanet.com/"));
        });
    
        go(function() {
            Co::sleep(1);
            echo "done
    ";
        });
    });
    echo 1;//可以得到执行

    关于协程,我们需要注意以下几点:

    - 不可以嵌套 Co un()。(Co un() 里面的逻辑如果有未处理的事件在 Co un() 之后就进行 EventLoop,后面的代码将得不到执行,反之,如果没有事件了将继续向下执行,可以再次 Co un()。)

    - 上文的 Co un() 函数其实是对 SwooleCoroutineScheduler 类 (协程调度器类) 的封装,下面我们就一起详细了解 SwooleCoroutineScheduler 的成员。

    成员函数

    1) set():设置协程运行时参数。是 Coroutine::set 方法的别名。

    SwooleCoroutineScheduler->set(array $options): bool

     示例 :

    $sch = new CoScheduler;
    $sch->set(['max_coroutine' => 100]);

    2) getOptions():获取设置的协程运行时参数。是 Coroutine::getOptions 方法的别名。

    SwooleCoroutineScheduler->getOptions(): null|array

    3) add():添加任务

    SwooleCoroutineScheduler->add(callable $fn, ... $args): bool

    $fn:回调函数

    $args:可选参数,将传递给协程

    示例:

    $scheduler = new SwooleCoroutineScheduler;
    $scheduler->add(function ($a, $b) {
        Co::sleep(1);
        echo assert($a == 'hello') . PHP_EOL;
        echo assert($b == 12345) . PHP_EOL;
        echo "Done.
    ";
    }, "hello", 12345);
    
    $scheduler->start();

    注意:与 go 函数不同,这里添加的协程不会立即执行,而是等待调用 start 方法时,一起启动并执行。如果程序中仅添加了协程,未调用 start 启动,协程函数 $fn 将不会被执行。

    4) parallel():添加并行任务。与 add 方法不同,parallel 方法会创建并行协程。在 start 时会同时启动 $num 个 $fn 协程,并行地执行。

    SwooleCoroutineScheduler->parallel(int $num, callable $fn, ... $args): bool

    $num:启动协程的个数

    $fn:回调函数

    $args:可选参数,将传递给协程

    示例:

    $sch = new SwooleCoroutineScheduler;
    
    $sch->parallel(10, function ($t, $n) {
        Co::sleep($t);
        echo "Co ".Co::getCid()."
    ";
    }, 0.05, 'A');
    
    $sch->start();

    5) start():启动程序,遍历 add 和 parallel 方法添加的协程任务,并执行。

    SwooleCoroutineScheduler->start(): bool

    返回值:启动成功,会执行所有添加的任务,所有协程退出时 start 会返回 true;启动失败返回 false,原因可能是已经启动了或者已经创建了其他调度器无法再次创建

    ---------------------------  我是可爱的分割线  ----------------------------

    最后博主借地宣传一下,漳州编程小组招新了,这是一个面向漳州青少年信息学/软件设计的学习小组,有意向的同学点击链接,联系我吧。

  • 相关阅读:
    synchronized锁机制 之 代码块锁(转)
    执行mvn 报错 source-1.5 中不支持 diamond运算符
    Git常用命令及场景
    mysql数据库导入与导出
    Linux磁盘空间分析及清理(df、du、rm)
    IIs配置文件存放路径
    解决SQLite database is locked
    C#测试web服务是否可用
    Jquery easyui-combobox 的一个BUG
    iframe自适应方法
  • 原文地址:https://www.cnblogs.com/ddcoder/p/14275960.html
Copyright © 2011-2022 走看看