You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<?phpuseReqwest\Client;
usefunctionAmp\async;
usefunctionAmp\Future\await;
require'vendor/autoload.php';
Client::init();
functiontest(int$delay): void {
$url = "https://httpbin.org/delay/$delay";
$t = time();
echo"Making async reqwest to $url that will return after $delay seconds...".PHP_EOL;
Client::get($url);
$t = time() - $t;
echo"Got response from $url after ~".$t." seconds!".PHP_EOL;
};
$futures = [];
$futures []= async(test(...), 5);
$futures []= async(test(...), 5);
$futures []= async(test(...), 5);
await($futures);
用法
cd examples/reqwest && \
cargo build && \
composer update && \
php -d extension=../../target/debug/libexample_reqwest.so test.php
结果
Making async reqwest to https://httpbin.org/delay/5 that will return after 5 seconds...
Making async reqwest to https://httpbin.org/delay/5 that will return after 5 seconds...
Making async reqwest to https://httpbin.org/delay/5 that will return after 5 seconds...
Got response from https://httpbin.org/delay/5 after ~5 seconds!
Got response from https://httpbin.org/delay/5 after ~5 seconds!
Got response from https://httpbin.org/delay/5 after ~5 seconds!
https://github.com/amphp/amp
什么是异步编程?
当使用PHP编写的应用程序I/O任务时,程序会在执行某个任务之前,一定要等待之前的任务完成,这时CPU会有很多时间处于空闲状态,这不仅会降低应用程序性能,还会降低硬件利用率。比如,当程序需要从数据库中读取大量的数据时,由于需要等待I/O操作完成,程序的执行速度会非常缓慢。因此,我们通过事件库,在程序执行的过程中,不需要等待某个任务完成才能执行下一个任务。这种编程模式可以极大地提高程序的效率和响应速度,尤其在处理复杂的I/O操作时表现得更为出色,而这就是异步编程。
Amphp
Amphp/Amp 是一个轻量级、高效的PHP异步库,为开发人员提供了一种处理I/O密集型任务和网络操作的新方式。它基于coroutine(协程)模型,让你能够编写出并发执行的任务,从而最大化服务器资源利用率,提高应用性能。
revolt也是amp家贡献出来的,本来属于amp内核,后来单拎出来了 不得不说,非常伟大
也不能这么说,amp和reactorPHP一起搞的 最早是reactorPHP,比amp要早
核心技术
Amp的核心是它的事件循环和coroutine(协程)支持。事件循环监听系统级别的事件,如文件描述符的状态变化或定时器触发,而coroutine则允许代码在不阻塞主线程的情况下进行暂停和恢复。这种设计使得开发者可以以同步代码的风格编写异步程序,降低了异步编程的学习曲线。此外,Amp还提供了Promise/Try机制,这是一套处理异步操作成功与失败的工具。通过Promise对象,你可以轻松地链式处理异步操作,并优雅地处理错误。
应用场景
网络I/O: Amp非常适合处理大量HTTP请求、TCP连接或其他网络通信,如:Websocket。它可以并行处理这些连接,显著提升Web服务的吞吐量。数据库交互: 异步数据库操作可以大大提高数据读取和写入的速度,尤其是在需要处理多个查询时。文件系统操作: 读写大文件或者遍历大量目录时,Amp可以通过异步操作避免阻塞主线程。后台任务: 对于耗时较长的后台任务,如数据处理、爬虫或批量更新,Amp可以实现更快的执行速度。
AMPHP是一个事件驱动的PHP库集合,设计时考虑了纤程和并发性。amphp/amp专门提供了future和cancellation作为异步编程的基本原语。我们现在使用Revolt,而不是使用amphp/amp发布事件循环实现。PHP大量使用PHP 8.1附带的纤程来编写异步代码,就像同步、阻塞代码一样。与早期版本相比,不需要基于生成器的协程或回调。与线程类似,每个纤程都有自己的调用堆栈,但纤程由事件循环协同调度。使用Amp\async()并发运行。
动机
传统上,PHP遵循顺序执行模型。PHP引擎按顺序一行接一行地执行。然而,程序通常由多个独立的子程序组成,这些子程序可以同时执行。如果查询数据库,则以阻塞方式发送查询并等待数据库服务器的响应。一旦你有了答案,你就可以开始做下一件事。我们可以发送下一个数据库查询,或者对一个API执行HTTP调用,而不是坐在那里什么也不做。让我们利用我们通常花在等待I/O上的时间!Revolt允许这样的并发I/O操作。我们通过避免回调来保持低认知负荷。我们的API可以像任何其他库一样使用,除了它们也可以并发工作,因为我们在后台使用了非阻塞I/O。使用Amp\async()并发运行,并在需要时使用Future::await()等。多年来,在PHP中实现并发的技术有很多,例如PHP 5中的回调和生成器。这些方法都有“你的函数是什么颜色”的问题,我们通过PHP 8.1中的Fibers解决了这个问题。它们允许多个独立调用堆栈的并发性。纤程由事件循环协同调度,这就是为什么它们也被称为协程。重要的是要理解,在任何给定的时间只有一个协程在运行,所有其他协程在此期间暂停。
你可以将协程比作一台使用单个CPU内核运行多个程序的计算机。每个程序都有一个执行时间段。然而,协程并不是抢占式的。他们没有固定的时间。他们必须主动给予事件循环的控制权。任何阻塞I/O函数在等待I/O时阻塞整个进程。你会想要避开他们。如果你还没有阅读安装指南,可以看看Hello World示例,它演示了阻塞函数的效果。AMPHP提供的库避免了I/O阻塞。
安装
如果您使用这个库,很可能希望使用Revolt来调度事件,您应该单独要求Revolt,即使它是作为依赖项自动安装的。
这些包为PHP中的异步/并发应用程序提供了基本的构建块。我们提供了很多建立在这些基础上的软件包。例如以下
amphp/byte-stream提供流抽象
amphp/socket为UDP和TCP(包括TLS)提供套
amphp/parallel提供并行处理以利用多个CPU内核并卸载阻塞操作
amphp/http-client提供HTTP/1.1和HTTP/2客户端
amphp/http-server提供HTTP/1.1和HTTP/2应用服务器
amphp/mysql和amphp/postgres用于非阻塞数据库访问
要求
此软件包需要PHP 8.1或更高版本。无需扩展!仅当应用需要大量并发套接字连接时才需要扩展,通常此限制配置为最多1024个文件描述符。
协程
协同程序是可中断的功能。在PHP中,它们可以使用纤程来实现。
在任何给定的时间,只有一个纤程在运行。当协程挂起时,协程的执行会暂时中断,允许其他任务运行。一旦计时器到期,流操作可能,或任何等待的Future完成,执行将恢复。
协同程序的低级挂起和恢复由Revolt的SuspensionAPI处理。
在Revolt事件循环上注册的回调会自动作为协程运行,挂起它们是安全的。除了事件循环API,Amp\async()还可以用来启动独立的调用栈。
另外 php-tokio 使用 PHP 的任何异步 Rust 库!
https://github.com/danog/php-tokio
它与revolt完全集成:这使得它与amphp、PSL和 reactphp 完全兼容。
下面是一个示例,使用异步 Rust reqwest库从 PHP 发出异步 HTTP 请求:
以下是使用 php-tokio 构建的异步 PHP 扩展列表(通过编辑此文件添加您的扩展!):
nicelocal/mongo-php-async-driver - 异步 MongoDB PHP 扩展
The text was updated successfully, but these errors were encountered: