Mix PHP V2 基于 Swoole 4 的 PHP Stream Hook 协程技术开发,协程使用方式与 Golang 几乎一致,包括框架封装的协程池、连接池、命令行处理都大量参考了 Golang 的系统库风格。
除了缺少 select case 外,Mix PHP 与 Golang 的协程几乎一致,框架还提供了连接池、协程池、命令行处理这些开箱即用的封装。
xgo 类似 Golang 的 go 关键字,可启动一个新的协程,Channel 等于 Golang 的 chan 类,负责在不同协程中传递数据。
<?php
namespace Console\Commands;
use Mix\Core\Coroutine\Channel;
use Mix\Core\Event;
/**
* Class CoroutineCommand
* @package Console\Commands
* @author liu,jian <[email protected]>
*/
class CoroutineCommand
{
/**
* 主函数
*/
public function main()
{
xgo(function () {
$time = time();
$chan = new Channel();
for ($i = 0; $i < 2; $i++) {
xgo([$this, 'foo'], $chan);
}
for ($i = 0; $i < 2; $i++) {
$result = $chan->pop();
}
println('Total time: ' . (time() - $time));
});
Event::wait();
}
/**
* 查询数据
* @param Channel $chan
*/
public function foo(Channel $chan)
{
$db = app()->dbPool->getConnection();
$result = $db->createCommand('select sleep(5)')->queryAll();
$db->release(); // 不手动释放的连接不会归还连接池,会在析构时丢弃
$chan->push($result);
}
}
执行结果为 5s,说明是并行执行的。
WaitGroup 与 Golang 的完全一致,xdefer 方法也等同于 Golang 的 defer 关键字。
当并行执行且不需要返回结果时,可以使用 WaitGroup + xdefer,xdefer 即使在方法抛出异常时,仍然会执行,这样能避免一直处于阻塞状态。
<?php
namespace Console\Commands;
use Mix\Concurrent\Sync\WaitGroup;
use Mix\Core\Event;
/**
* Class WaitGroupCommand
* @package Console\Commands
* @author liu,jian <[email protected]>
*/
class WaitGroupCommand
{
/**
* 主函数
*/
public function main()
{
xgo(function () {
$wg = WaitGroup::new();
for ($i = 0; $i < 2; $i++) {
$wg->add(1);
xgo([$this, 'foo'], $wg);
}
$wg->wait();
println('All done!');
});
Event::wait();
}
/**
* 查询数据
* @param WaitGroup $wg
*/
public function foo(WaitGroup $wg)
{
xdefer(function () use ($wg) {
$wg->done();
});
println('work');
throw new \RuntimeException('ERROR');
}
}
即便抛出了 RuntimeException 异常,仍然能执行到 println('All done!');
,没有导致 wg 内的 chan 一直处于阻塞状态。
异步编程中,定时器的使用非常频繁。
Timer::new()
可获得一个实例after
方法可设置一次性定时tick
方法可设置持续定时$timer->clear();
方法。<?php
namespace Console\Commands;
use Mix\Core\Event;
use Mix\Core\Timer;
/**
* Class TimerCommand
* @package Console\Commands
* @author liu,jian <[email protected]>
*/
class TimerCommand
{
/**
* 主函数
*/
public function main()
{
// 一次性定时
Timer::new()->after(1000, function () {
println(time());
});
// 持续定时
$timer = new Timer();
$timer->tick(1000, function () {
println(time());
});
// 停止定时
Timer::new()->after(10000, function () use ($timer) {
$timer->clear();
});
Event::wait();
}
}
支持的用户请加个 Star 吧,让更多人发现 MixPHP。https://github.com/mix-php/mix
1
onanying OP 尴尬,为何没有回复?
|
2
ETO 2019-04-19 08:53:01 +08:00
表示有点不太看得懂,最近准备看一下 swool 相关的东西。
|
3
dvaknheo 2019-04-21 16:52:35 +08:00
没看出 和 Swoole 原生的相比改进了什么
|