【PHP】PHP8.1新特性大讲解之Fibers with a grain of salt
Fibers with a grain of salt
所以我打算写一篇关于在PHP 8.1 中使用Fibers纤维的深入博客文章。我们将从一个基本示例开始,从头开始解释它们。这个想法是发送异步 HTTP 请求并使用纤程并行处理它们。
但是和他们一起玩,我了解到RFC并不是在开玩笑,当它说“不应直接在应用程序级代码中使用 Fiber API。Fibers 提供了一个基本的、低级的流控制 API 来创建更高然后在应用程序代码中使用的级抽象”。
因此,与其走这条路并使事情变得过于复杂,我们将讨论什么是纤程概念,为什么它们在应用程序代码中几乎不可用,以及您到底如何使用异步 PHP。
首先,一点点理论。
假设您要发送三个 HTTP 请求并处理它们的组合结果。这样做的同步方式是发送第一个,等待响应,然后发送第二个,等待,等等。
让我们用尽可能简单的图表来表示这样的程序流程。你需要从上到下阅读这张图表,时间越往下越走。每种颜色代表一个 HTTP 请求。每个请求的彩色部分代表实际运行的 PHP 代码,您服务器上的 CPU 正在执行工作,透明块代表等待时间:请求需要通过网络发送,其他服务器需要处理并发送回. 只有当响应到达时,我们才能再次工作。
这是一个同步执行流程:发送、等待、处理、重复。
在并行处理的世界中,我们发送请求但不等待。然后我们发送下一个请求,然后是另一个。只有然后我们等待所有请求。在等待的同时,我们会定期检查我们的一个请求是否已经完成。如果是这种情况,我们可以立即处理。
您可以看到这种方法如何减少执行时间,因为我们更优化地使用了等待时间。
Fibers 是 PHP 8.1 中的一种新机制,可让您更有效地管理这些并行执行路径。使用生成器和 已经可以实现yield,但是纤维是一个显着的改进,因为它们是专门为此用例设计的。
您将为每个请求创建一个纤程,并在请求发送后暂停纤程。创建所有三个光纤后,您将遍历它们,并一一恢复它们。通过这样做,纤程检查请求是否已经完成,如果没有则再次暂停,否则它可以处理响应并最终完成。
你看,纤程是一种启动、暂停和恢复程序隔离部分执行流程的机制。Fiber 也被称为“绿色线程”:实际上存在于同一进程中的线程。这些线程不是由操作系统管理的,而是由运行时管理的——在我们的例子中是 PHP 运行时。它们是管理某些形式的并行编程的一种经济高效的方式。
但请注意,它们并没有添加任何真正的异步内容:所有纤程都位于同一个 PHP 进程中,并且一次只能运行一个纤程。这是循环它们并在等待时检查它们的主进程,该循环通常称为“事件循环”。
并行性的难点不在于你如何在纤程或生成器上循环,或者你想使用的任何机制;它是关于能够开始一个操作,将它交给一个外部服务,并且只在你想要的时候以非阻塞的方式检查结果。
看,在前面的例子中,我们假设我们可以只发送一个请求,然后在我们想要的时候检查它的响应,但这实际上并不像听起来那么容易。
没错:大多数处理 I/O 的 PHP 函数都没有内置这种非阻塞功能。事实上,只有少数函数可以做到,而且使用它们非常麻烦。
有一个套接字的例子,它可以被设置为非阻塞,像这样:
[$read, $write] = stream_socket_pair( STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP ); stream_set_blocking($read, false); stream_set_blocking($write, false);
通过使用stream_socket_pair(),创建了两个可用于双向通信的套接字。正如您所看到的,它们可以使用stream_set_blocking().
假设我们想要实现我们的示例,发送三个请求。我们可以使用套接字来做到这一点,但我们需要在它之上自己实现 HTTP 协议。这正是nox7所做的,该用户在Reddit上分享了一个小型概念证明,以展示如何使用光纤和套接字发送 HTTP GET 请求。你真的想在你的应用程序代码中这样做吗?
至少对我来说,答案是“不”。这正是 RFC 警告的内容;我不生气。相反,我们鼓励使用现有的异步框架之一:Amp或ReactPHP。
例如,使用 ReactPHP,我们可以这样写:
$loop = React\EventLoop\Factory::create(); $browser = new Clue\React\Buzz\Browser($loop); $promises = [ $browser->get('https://example.com/1'), $browser->get('https://example.com/2'), $browser->get('https://example.com/3'), ]; $responses = Block\awaitAll($promises, $loop);
与手动创建套接字连接相比,这是一个更好的示例。这就是 RFC 的意思:应用程序开发人员不需要担心纤程,它是 Amp 或 ReactPHP 等框架的实现细节。
不过,这给我们带来了一个问题:与我们已经可以用发电机做的事情相比,纤维有什么好处?RFC 是这样解释的:
与无堆栈生成器不同,每个 Fiber 都有自己的调用堆栈,允许它们在深度嵌套的函数调用中暂停。声明中断点的函数(即调用 Fiber::suspend())不需要更改其返回类型,这与使用 yield 的函数必须返回 Generator 实例不同。
Fiber 可以在任何函数调用中挂起,包括那些从 PHP VM 内部调用的函数,例如提供给 array_map 的函数或迭代器对象上的 foreach 调用的方法。
很明显,纤程在语法和灵活性方面都有显着的改进。但与 Go 及其“ goroutines ”相比,它们还不算什么。
要使异步 PHP 在没有框架开销的情况下成为主流,仍然缺少许多功能,而 Fiber 是朝着正确方向迈出的良好一步,但我们还没有做到这一点。
所以就是这样。如果您不是 Amp、ReactPHP 或较小的异步 PHP 框架的维护者,那么实际上没有什么可说的。也许更多的框架或库将开始合并它们?
同时,还有Swoole——一个 PHP 扩展,它实际上将几个核心功能修改为非阻塞。Swoole 本身是一个中文项目,在涉及英语时通常没有很好的文档记录,但最近 Laravel宣布与它进行第一方集成。也许这是将 PHP 推向更异步模型的更好策略:可选择将 Swoole 或其他扩展与 Laravel 和 Symfony 等框架集成?
猜你喜欢
- 【PHP】php加密算法有哪些
- php加密算法有MD5算法、SHA算法、AES算法、RSA算法、Base64编码、DES算法、RC4算法、Blowfish算法等。详细介绍:1、MD5算法,用于将任意长度的数据转换为固定长度的哈希值,在PHP中可以使用md5()函数来计算字符串的MD5哈希值;2、SHA算法,包括SHA-1、SHA-256、SHA-512等,这些算法在PHP中都有对应的函数;3、AES算法等等。本教程操作系统:windows10系统、PHP8.1.3版本、Dell G3电脑。PHP是一种广泛使用的服务器
- 【PHP】PHP8如何创建可扩展的应用程序
- 深入掌握PHP8底层开发原理与新特性:如何创建可扩展的应用程序导语随着互联网技术的发展,PHP成为最受欢迎的Web开发语言之一。PHP语言的最新版本PHP8在底层开发原理和新特性方面做了很多改进和优化,使得开发者可以更好地创建可扩展的应用程序。本文将带您深入探索PHP8的底层开发原理和新特性,并给出代码示例来帮助您更好地理解。一、PHP8底层开发原理的改进JIT编译器的引入PHP8引入了JIT(Just-In-Time)编译器,通过将PHP代码转换成本地机器码,使得PHP代码的执行速度得到了显著
- 【PHP】linux系统php怎么安装curl扩展
- 有时候安装好php后,后面需要一些扩展需要添加进来,又不能影响当前php的工作,我们就只能通过动态添加扩展来实现。php安装curl扩展的方法:一.首先明确一些目录1.源码包目录,就是放从网上下载的源码包文件的目录,里面有下载的php,mysql,http等源码例如:/usr/local/src/ 2.PHP扩展包路径,就是PHP用来支持扩展服务的软件包,一般在php源码包的ext目录例如:/usr/local/src/php-7.0.12/ext/二. 开始动手安装1.安装curl
- 【PHP】php替换字符串
- 在PHP中,字符串替换是常见的操作,而替换所有匹配的字符串更是常见需求。本文将详细介绍如何使用PHP中的替换函数来替换所有匹配字符串。一、str_replace函数PHP中最常用的替换函数是str_replace()函数,它可以替换一个字符串中的指定部分。其语法如下:string str_replace(mixed $search, mixed $replace, mixed $subject[, int
- 【PHP】使用intervention/image给图片添加文字和图片
- 准备使用composer安装composer require intervention/image我安装的版本是2.7一、 给图片添加文字use Intervention\Image\ImageManagerStatic as Image; public function addTextToImage($imagePath, $text, $fontPath, $x =&n
- 【PHP】PHP开发中如何使用Nginx实现负载均衡
- 在现代web应用开发中,高并发访问是一个必须要面对的挑战。负载均衡是解决这个问题的一种有效的方案。在php开发中,使用nginx实现负载均衡是一个非常常见的方法。本文将详细介绍如何在php开发中使用nginx实现负载均衡。一、Nginx及负载均衡的基本概念NginxNginx是一款轻量级的高性能的web服务器和反向代理服务器。它的出现解决了Apache这样的传统web服务器在高并发访问下的性能瓶颈。Nginx具有极高的性能、稳定性和安全性,并且支持大量的并发连接。负载均衡负载均衡是一种将网络流量
- 【PHP】PHP生成ICO图标的方法
- 本篇文章给大家介绍一下使用php生成ico图标的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。ico图标在每个网站中都需要用到的,使用方法也是很简单的,基本上以下面的方式为主,但也有其他的方式。<link rel="shortcut icon" href="/favicon.ico">一般将ico图标放置在网站的根目录下,使用时可以使用相对路径,也可以使用绝对路径来引入,这个没有明确的规定。
- 【PHP】php判断字符串是否是中文
- 可以判断。判断方法:1、使用preg_match()函数配合正则来判断是否全是中文 ,语法“!preg_match("/[^\x80-\xff]/i",$str)”;2、使用preg_match()函数配合正则来判断是否包含中文 ,语法“preg_match("/[\x7f-\xff]/", $str)”或“preg_match('/[^\x00-\x80]/',$str)”。本教程操作环境:windows7系统、PHP8.1版、