三十二、Swoole 基础学习笔记 - Swoole 协程容器

作者: 温新

分类: 【Swoole 系列】

阅读: 1603

时间: 2023-03-13 12:18:10

hi,我是温新,一名PHPer

文章基于 Swoole 5.0.1 版本编写。

学习目标:学习协程容器

说明:本篇文章结合官方文档编写及参考网络资料编写,虽非全部原创,但也是结合了自己的理解,若转载请附带本文 URL,编写不易,持续编写更不易,谢谢!

所有的协程必须在协程容器中创建,Swoole 程序启动时大部分情况会自动创建协程容器,用 Swoole 启动程序的方式一共有三种:

  • 1、调用异步风格服务端程序的 start 方法,此种启动方式会在事件回调中创建协程容器;

  • 2、调用 Swoole 提供的 2 个进程管理模块 Process 和 Process\Pool 的 start 方法,此种启动方式会在进程启动的时候创建协程容器;

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

全协程 HTTP 服务

Swoole\Coroutine\run(function () {
    $server = new Swoole\Coroutine\Http\Server('0.0.0.0', 9501, false);
    $server->handle('/', function ($reqeust, $response) {
        $response->header('Content-Type', 'text/html; charset=utf-8');
        $response->end('<h1>hi,我是王美丽</h1>');
    });
    $server->handle('/test', function ($reqeust, $response) {
        $response->header('Content-Type', 'text/html; charset=utf-8');
        $response->end('<h1>hi,我是郝帅</h1>');
    });
    $server->handle('/stop', function ($request, $response) use ($server) {
        $response->end("<h1>Stop</h1>");
        $server->shutdown();
    });
    
    $server->start();
});

// 不执行 stop,该行不会被输出
echo '我来自外星,我会被输出吗?';

协程并发操作

Swoole\Coroutine\run(function () {
    Swoole\Coroutine::create(function () {
        echo strlen(file_get_contents('https://www.baidu.com')) . PHP_EOL;
    });
    Swoole\Coroutine::create(function () {
        Swoole\Coroutine::sleep(1);
        echo '嗨,我要去火星了' . PHP_EOL;
    });
});
echo '我会被执行' . PHP_EOL;

输出结果

$php 32-swoole-coroutine-scheduler.php 
9508
嗨,我要去火星了
我会被执行

协程容器

Swoole\Coroutine\run() 函数其实是对 Swoole\Coroutine\Scheduler 类(协程调度器)的封装。

下面是对 Scheduler 类的相关方法学习。

相关方法

set

含义:设置协程运行时参数。

语法:

Swoole\Coroutine\Scheduler->set(array $options): bool
# 参数:该参数选项等同于协程容器中的 set() 方法参数。

add

含义:添加任务。

语法:

Swoole\Coroutine\Scheduler->add(callable $fn, ... $args): bool
# 参数:
    $fn:回调函数;
    $args:可选参数,将传递给协程

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

getOptions

含义:获取设置的协程运行时参数。

语法:

Swoole\Coroutine\Scheduler->getOptions(): null|array
# 参数:该参数选项等同于协程容器中的 getOptions() 方法参数。

start

含义:启动程序。

语法:Swoole\Coroutine\Scheduler->start(): bool

返回值:

​ 启动成功,会执行所有添加的任务,所有协程退出时 start 会返回 true

​ 启动失败返回 false,原因可能是已经启动了或者已经创建了其他调度器无法再次创建。

遍历 addparallel 方法添加的协程任务,并执行。

parallel

含义:添加并行任务。

语法:

Swoole\Coroutine\Scheduler->parallel(int $num, callable $fn, ... $args): bool
    
# 参数:
$num:启动协程的个数
$fn:回调函数
$args:可选参数,将传递给协程

Scheduler 案例

基础案例

// 实例化协程容器
$scheduler = new Swoole\Coroutine\Scheduler;
// 设置协程参数
$scheduler->set([
    'max_coroutine' => 100,
]);
// 添加任务
$scheduler->add(function (string $name, int $age) {
    Swoole\Coroutine::sleep(1);
    echo '我是 ' . $name . ' ,我 ' . $age . PHP_EOL;
}, '王美丽', 18);
// 获取设置的参数
print_r($scheduler->getOptions());
// 启动程序
$scheduler->start();

输出结果

$php 32-swoole-coroutine-scheduler.php 
Array
(
    [max_coroutine] => 100
)
我是 王美丽 ,我 18

parallel 并行任务案例

$scheduler = new Swoole\Coroutine\Scheduler();
$scheduler->parallel(10, function () {
    echo '当前协程 ID ' . Swoole\Coroutine::getCid() . PHP_EOL;
});
$scheduler->start();

输出结果

$php 32-swoole-coroutine-scheduler.php 
当前协程 ID 1
当前协程 ID 2
当前协程 ID 3
当前协程 ID 4
当前协程 ID 5
当前协程 ID 6
当前协程 ID 7
当前协程 ID 8
当前协程 ID 9
当前协程 ID 10

我是温新,本篇文章结束。

请登录后再评论