Swoole协程并发调用
Swoole协程并发调用实现原理:
- 在
onRequest
中需要并发两个http
请求,可使用go
函数创建 2 个子协程,并发地请求多个URL
; - 并创建一个
chan
,使用use
必报引用语法,传递给子协程; - 主协程循环调用
chan-pop
,等待子协程完成任务,yield
进入挂起状态; - 并发的两个子协程其中某个完成请求时,调用
chan-push
将数据推送给主协程; - 子协程完成
URL
请求后退出,主协程从挂起状态中恢复,继续向下执行调用$response-end
发送响应结果。
第一步:编写代码
文件:d14.php
<?php
use Swoole\Coroutine\MySQL;
use Swoole\Coroutine\Redis;
// 创建HTTP服务器
$serv = new Swoole\Http\Server("127.0.0.1", 9503, SWOOLE_BASE);
// 监听
$serv->on('Request', function ($res, $resp) {
// 创建通道
$chan = new chan(2);
// 创建协程
go(function () use ($chan) {
var_dump(time());
// 连接mysql
$mysql = new MySQL();
$mysql->connect([
'host' => '127.0.0.1',
'user' => 'root',
'password' => '123456',
'database' => 'test',
]);
$result = $mysql->query('select sleep(3)');
// 将结果推送给主协程
$chan->push($result);
});
go(function () use ($chan) {
var_dump(time());
$redis1 = new Redis();
$redis1->connect('127.0.0.1', 6379);
$result = $redis1->set('hello','swoole');
$chan->push($result);
});
go(function () use ($chan) {
var_dump(time());
$redis2 = new Redis();
$redis2->connect('127.0.0.1', 6379);
$result = $redis2->get('hello');
$chan->push($result);
});
// 从通道中读取数据并存入数组
$results = [];
for ($i = 0; $i < 3; $i++) {
$results[] = $chan->pop();
}
// 响应请求
$resp->end(json_encode([
'data' => $results,
'time' => time()
]));
});
$serv->start();
第二步:运行http服务器
php d14.php
第三步:浏览器中访问
http://192.168.172.130:9503/
// 页面输出结果
{"data":["swoole",true,[{"sleep(3)":"0"}]],"time":1619270058}
第四步:查看http服务器
int(1619270058)
int(1619270058)
int(1619270058)
可以看到打印三个客户端请求时间是一致的,说明它们是并发执行的。
2021-04-21
请登录后再评论