PHP 8.1 新增异步编程 Fibers

PHP 8.1 新增异步编程 Fibers

PHP 一直在尝试补足自身的短板,将在今年年末的 PHP 8.1 版本中引入的异步编程:Fiber。Fiber 是一种轻量级线程,通常叫作协程,许多主流语言都有他们自己的异步编程实现方式,但原理都一样:让计算机同时执行多个任务。

Fiber 就像汽车一样,可以启动运行,可以刹车等待,也可以恢复行驶。

final class Fiber
{
    public function __construct(callable $callback) {}
    public function start(mixed ...$args): mixed {}
    public function resume(mixed $value = null): mixed {}
    public function throw(Throwable $exception): mixed {}
    public function isStarted(): bool {}
    public function isSuspended(): bool {}
    public function isRunning(): bool {}
    public function isTerminated(): bool {}
    public function getReturn(): mixed {}
    public static function this(): ?self {}
    public static function suspend(mixed $value = null): mixed {}
}

当你创建了一个新的带有回调参数的 Fiber 实例后,回调函数并不会被执行,直到你 start 以后,你的回调函数才会被执行。

$fiber = new Fiber(function() : void {
   echo "I'm running a Fiber, yay!";
});

$fiber->start(); // I'm running a Fiber, yay!

这段代码看起来像是同步代码,但实际上是异步的。如果你在回调里调用 Fiber::suspend() 程序将会暂停,然后将 CPU 控制权转交出去,这很像汽车的自动驻车功能,当你踩刹车到停车(调用 Fiber::suspend()),自动驻车将会发生作用,汽车的引擎仍然在工作,并没有熄火,然后你一碰一下油门(调用 Fiber::resume()),车又会跑起来。

$fiber = new Fiber(function() : void {
   Fiber::suspend();
   echo "I'm running a Fiber, yay!";
});

$fiber->start(); // [Nothing happens]

$fiber->resume(); // I'm running a Fiber, yay!

start()suspend()resume() 都有一个参数:

  • start() 方法将把参数传递给可调用的方法,并将返回 suspend() 方法收到的任何值。
  • suspend() 方法将返回 resume() 方法收到的任何值。
  • resume() 方法将返回下一次调用 suspend() 方法所收到的任何值。

这使得主线程和 Fiber 之间的通信相对容易:

  • resume() 用于将用 suspend() 接收到的值传递给 Fiber 中。
  • suspend() 用于将 resume() 接收到的值传递出去。
$fiber = new Fiber(function (): void {
    $value = Fiber::suspend('fiber');
    echo "Value used to resume fiber: ", $value, "n";
});

$value = $fiber->start();

echo "Value from fiber suspending: ", $value, "n";

$fiber->resume('test');

这段代码的执行结果如下:

Value from fiber suspending: fiber
Value used to resume fiber: test

Fiber 可能会打开一扇门,让 PHP 更有效地使用 socket,并启用像 WebSockets、服务器端事件、数据库连接池,甚至 HTTP/3 这样的东西,而不必求助于编译扩展、将 PHP 封装到另一个外部运行时或任何其他野路子。

根据文档,Fiber 只允许用户代码在 PHP 中实现全栈coroutines或绿色线程

换句话说,除非你有一个非常奇怪的理由直接使用它们,否则你永远不会像在 Javascript 或 Go 上做 coroutines 那样与 Fiber 交互。

一些框架如 Symfony、Laravel、CodeIgniter 和 CakePHP 等还需要一些时间来引入Fiber,并加以封装。还有一些框架,如 ReactPHP,已经在其最新的开发版本中使用了 Fiber。

我个人主要使用 Laravel 框架,写此文,基于 Swoole 和 RoadRunner 的 Laravel Octane 还没有正式发布,但本质上是两码事儿。

版权声明:
作者:coderlxc
链接:https://coderlxc.com/php-8-1-new-asynchronous-programming-fibers
来源:月光酒馆
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>