协程可以简单理解为线程,只不过这个线程是用户态的,不需要操作系统参与,创建销毁和切换的成本非常低,和线程不同的是协程没法利用多核 cpu 的,想利用多核 cpu 需要依赖 Swoole
的多进程模型。
PHP
层协程框架,开发者不需要使用 yield
关键词来标识一个协程 IO
操作,所以不再需要对 yield
的语义进行深入理解以及对每一级的调用都修改为 yield
,这极大的提高了开发效率。IO
密集型应用,因为协程在 IO
阻塞 时会自动调度,减少 IO
阻塞导致的时间损失。 高并发服务,如秒杀系统、高性能API接口、RPC服务器,连接池,IM聊天、游戏服务器、物联网、消息服务器等。
用户可以通过go函数创建一个协程,以达到并发执行的效果,如下面代码所示:
go(function () {
echo "one" . PHP_EOL;
});
go(function () {
echo "two" . PHP_EOL;
});
go(function () {
echo "three" . PHP_EOL;
});
通过协程可以并发执行客户端请求,使用到协程调度带来的 IO
阻塞时的调度,来实现高性能服务,下面是通过 defer
机制实现请求的并发执行:
go(function () {
// 协程 MySQL 客户端
$mysql = new Swoole\Coroutine\MySQL();
$mysql->connect([
'host' => '172.17.0.1',
'user' => 'root',
'password' => 'root',
'database' => 'swoole',
]);
$mysql->setDefer();
$mysql->query('select sleep(2);');
print_r("time1: " . time() . PHP_EOL);
// 协程 Redis 客户端
$redis = new Swoole\Coroutine\Redis();
$redis->connect('172.17.0.1', 6379);
$redis->setDefer();
$redis->set('name', '张三');
$redis->recv();
print_r("time2: " . time() . PHP_EOL);
$redis->setDefer();
$redis->get('name');
$res1 = $mysql->recv();
$res2 = $redis->recv();
print_r(['result1: ' => $res1[0]['sleep'], 'result2: ' => $res2, 'time3: ' => time()]);
});
setDefer(true)
后,通过 Redis 或 MySQL 客户端发起请求,将不再等待服务器返回结果,而是在发送请求之后,立即返回 true
。在此之后可以继续发起其他 Redis、MySQL 请求,最后再使用 recv()
方法接收响应内容。static
变量的一致性。如果你觉得这篇文章对你有点用的话,麻烦请给我们的开源项目点点star:http://github.crmeb.net/u/defu不胜感激 !
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。