您的当前位置:首页>全部文章>文章详情

【PHP】PHP8.1新特性大讲解之Fibers with a grain of salt

CrazyPanda发表于:2024-01-04 23:30:09浏览:300次TAG:


Fibers with a grain of salt

所以我打算写一篇关于在PHP 8.1 中使用Fibers纤维的深入博客文章。我们将从一个基本示例开始,从头开始解释它们。这个想法是发送异步 HTTP 请求并使用纤程并行处理它们。

但是和他们一起玩,我了解到RFC并不是在开玩笑,当它说“不应直接在应用程序级代码中使用 Fiber API。Fibers 提供了一个基本的、低级的流控制 API 来创建更高然后在应用程序代码中使用的级抽象”。

因此,与其走这条路并使事情变得过于复杂,我们将讨论什么是纤程概念,为什么它们在应用程序代码中几乎不可用,以及您到底如何使用异步 PHP。

首先,一点点理论。

假设您要发送三个 HTTP 请求并处理它们的组合结果。这样做的同步方式是发送第一个,等待响应,然后发送第二个,等待,等等。

让我们用尽可能简单的图表来表示这样的程序流程。你需要从上到下阅读这张图表,时间越往下越走。每种颜色代表一个 HTTP 请求。每个请求的彩色部分代表实际运行的 PHP 代码,您服务器上的 CPU 正在执行工作,透明块代表等待时间:请求需要通过网络发送,其他服务器需要处理并发送回. 只有当响应到达时,我们才能再次工作。

1.png


这是一个同步执行流程:发送、等待、处理、重复。

在并行处理的世界中,我们发送请求但不等待。然后我们发送下一个请求,然后是另一个。只有然后我们等待所有请求。在等待的同时,我们会定期检查我们的一个请求是否已经完成。如果是这种情况,我们可以立即处理。

1.png

您可以看到这种方法如何减少执行时间,因为我们更优化地使用了等待时间。

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是一种广泛使用的服务器
发表于:2023-12-06 浏览:306 TAG:
【PHP】PHP8如何创建可扩展的应用程序
深入掌握PHP8底层开发原理与新特性:如何创建可扩展的应用程序导语随着互联网技术的发展,PHP成为最受欢迎的Web开发语言之一。PHP语言的最新版本PHP8在底层开发原理和新特性方面做了很多改进和优化,使得开发者可以更好地创建可扩展的应用程序。本文将带您深入探索PHP8的底层开发原理和新特性,并给出代码示例来帮助您更好地理解。一、PHP8底层开发原理的改进JIT编译器的引入PHP8引入了JIT(Just-In-Time)编译器,通过将PHP代码转换成本地机器码,使得PHP代码的执行速度得到了显著
发表于:2024-01-07 浏览:310 TAG:
【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
发表于:2024-03-19 浏览:292 TAG:
【PHP】php替换字符串
在PHP中,字符串替换是常见的操作,而替换所有匹配的字符串更是常见需求。本文将详细介绍如何使用PHP中的替换函数来替换所有匹配字符串。一、str_replace函数PHP中最常用的替换函数是str_replace()函数,它可以替换一个字符串中的指定部分。其语法如下:string str_replace(mixed $search, mixed $replace, mixed $subject[, int 
发表于:2023-12-29 浏览:316 TAG:
【PHP】使用intervention/image给图片添加文字和图片
准备使用composer安装composer require intervention/image我安装的版本是2.7一、 给图片添加文字use Intervention\Image\ImageManagerStatic as Image;   public function addTextToImage($imagePath, $text, $fontPath, $x =&n
发表于:2024-04-02 浏览:279 TAG:
【PHP】PHP开发中如何使用Nginx实现负载均衡
在现代web应用开发中,高并发访问是一个必须要面对的挑战。负载均衡是解决这个问题的一种有效的方案。在php开发中,使用nginx实现负载均衡是一个非常常见的方法。本文将详细介绍如何在php开发中使用nginx实现负载均衡。一、Nginx及负载均衡的基本概念NginxNginx是一款轻量级的高性能的web服务器和反向代理服务器。它的出现解决了Apache这样的传统web服务器在高并发访问下的性能瓶颈。Nginx具有极高的性能、稳定性和安全性,并且支持大量的并发连接。负载均衡负载均衡是一种将网络流量
发表于:2024-05-29 浏览:342 TAG:
【PHP】PHP生成ICO图标的方法
本篇文章给大家介绍一下使用php生成ico图标的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。ico图标在每个网站中都需要用到的,使用方法也是很简单的,基本上以下面的方式为主,但也有其他的方式。<link rel="shortcut icon" href="/favicon.ico">一般将ico图标放置在网站的根目录下,使用时可以使用相对路径,也可以使用绝对路径来引入,这个没有明确的规定。
发表于:2024-01-30 浏览:306 TAG:
【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版、
发表于:2023-12-13 浏览:321 TAG:
【PHP】PHP中使用ElasticSearch
在es中,使用组合条件查询是其作为搜索引擎检索数据的一个强大之处,在前几篇中,简单演示了es的查询语法,但基本的增删改查功能并不能很好的满足复杂的查询场景,比如说我们期望像mysql那样做到拼接复杂的条件进行查询该如何做呢?es中有一种语法叫bool,通过在bool里面拼接es特定的语法可以做到大部分场景下复杂条件的拼接查询,也叫复合查询首先简单介绍es中常用的组合查询用到的关键词,filter:过滤,不参与打分 must:如果有多个条件,这些条件都必须满足 and与 should:如果有多个条
发表于:2024-07-26 浏览:258 TAG: #php #Elasticsearch
【PHP】进程、线程、协程的关系
进程: 是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态的概念,竞争计算机系统资源的基本单位; 线程: 是进程的一个执行单元,是进程内的调度实体,比进程更小的独立运行的基本单位,线程也被称为轻量级进程。 协程: 是一种轻量级的线程,因此又称微线程。它不是由操作系统内核调度,而是由程序员自己控制调度的执行流程。
发表于:2025-03-21 浏览:46 TAG: #php