【PHP】PHP8.1 Fiber交叉执行多任务
CrazyPanda发表于:2024-01-06 22:26:24浏览:313次
大家的电脑应该都是大等于2核的了,但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行,微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。(本文给大家抛个砖,欢迎大家补充更有意思的使用)
拿平时大家写的 for 循环举例。像 go 你可以写两个 go
每个里面各写一个循环同时输入,你可以看到输出是交替。在过去的php版本中,如果只开启一个 cli 写多个 for 循环,那么他的输出一定是顺序的。无法做到交叉输出(也就是无法在第一个循环中执行若干次后,让b再执行,b执行一段时间后,再让A执行)。
现在借助 fiber 我们也可以实现这种操作。【推荐学习:PHP视频教程】
下面这段代码就可以做到两个循环交叉执行。甚至可以控制两个程序执行的频率(比如A执行3次,B执行一次这样分配)
<?php $t1 = false; $t2 = false; $reg = []; $reg[] = new \Fiber(function () use (&$t1) { for ($i = 1; $i < 10; $i++) { echo $i; echo PHP_EOL; \Fiber::suspend(); } $t1 = true; }); $reg[] = new \Fiber(function () use (&$t2) { for ($i = 1; $i < 10; $i++) { echo $i; echo PHP_EOL; \Fiber::suspend(); } $t2 = true; }); $startTag = true; while (count($reg) > 1) { if ($startTag) foreach ($reg as $pI) { $pI->start(); $startTag = false; } foreach ($reg as $pI) { $pI->resume(); } if ($t1 === true && $t2 === true) { break; } }
1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9
你甚至可以控制两个循环的执行频率,比如 第一个循环 执行3次后,第二个循环执行一次。代码如下
<?php $reg = []; $fId = 1; $reg[$fId] = new \Fiber(function () use (&$reg, $fId) { for ($i = 1; $i < 10; $i++) { echo $fId . ':' . $i; echo PHP_EOL; if ($i % 3 == 0) { \Fiber::suspend(); } } unset($reg[$fId]); }); $fId++; $reg[$fId] = new \Fiber(function () use (&$reg, $fId) { for ($i = 1; $i < 10; $i++) { echo $fId . ':' . $i; echo PHP_EOL; \Fiber::suspend(); } unset($reg[$fId]); }); $startTag = true; while (count($reg) > 0) { if ($startTag) foreach ($reg as $pI) { $pI->start(); $startTag = false; } foreach ($reg as $pI) { $pI->resume(); } }
1:1 1:2 1:3 2:1 1:4 1:5 1:6 2:2 1:7 1:8 1:9 2:3 2:4 2:5 2:6 2:7 2:8 2:9
通过消息通知完成
<?php namespace App\Command; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; #[AsCommand( name: 'Sname', description: 'Add a short description for your command', )] class SnameCommand extends Command { protected function configure(): void { $this ->addArgument('arg1', InputArgument::OPTIONAL, 'Argument description') ->addOption('option1', null, InputOption::VALUE_NONE, 'Option description'); } protected function execute(InputInterface $input, OutputInterface $output): int { $t1 = false; $t2 = false; $reg = []; $fId = 1; $reg[] = new \Fiber(function () use ($fId) { for ($i = 1; $i < 10; $i++) { echo $fId . ':' . $i; echo PHP_EOL; if ($i % 3 == 0) { \Fiber::suspend(new SuspendData(Status::Running)); } } \Fiber::suspend(new SuspendData(Status::Stop)); }); $fId++; $reg[] = new \Fiber(function () use ($fId) { for ($i = 1; $i < 10; $i++) { echo $fId . ':' . $i; echo PHP_EOL; \Fiber::suspend(new SuspendData(Status::Running)); } \Fiber::suspend(new SuspendData(Status::Stop)); }); $startTag = true; while (count($reg) > 0) { if ($startTag) foreach ($reg as $pI) { $pI->start(); $startTag = false; } foreach ($reg as $key => $pI) { $r = $pI->resume(); if ($r->status === Status::Stop) { unset($reg[$key]); } } } return Command::SUCCESS; } } class SuspendData { public readonly Status $status; public function __construct($status) { $this->status = $status; } } enum Status { case Stop; case Running; }
猜你喜欢
- 【PHP】PHP中的ob系列函数
- 在PHP中,ob系列函数,又称输出控制函数,可用于缓冲输出控制。1. ob_start()功能:打开一个输出缓冲区,所有的输出内容不再直接输出到浏览器,而是保存在输出缓冲区里面。返回值:布尔值。2. ob_get_clean()功能:获取当前缓冲区的内容并删除(关闭)当前输出缓冲区。返回值:返回输出缓冲区的内容,并结束输出缓冲区;如果输出缓冲区不是活跃的,返回false。ob_get_clean() 实质上是一起执行了 ob_get_contents() 和 ob_end_clean() 。3.
- 【PHP】PHP面试题之算法题
- hp面试题中也会经常出现算法题,本文主要和大家分享PHP面试题之算法题,希望能帮助到大家。面试题——算法题:1、插入排序(一维数组) 基本思想:每次将一个待排序的数据元素,插入到前面已经排好序的数列中的适当位置,使数列依然有序;直到待排序数据元素全部插入完为止。 示例:[初始关键字] [49] 38 65 97 76 13 27 49J=2(38) [38 49] 65 97 76 13 27 49J=3(65) [38 49 65] 97 76 13 27 49J=4(97) [38 49
- 【PHP】一文搞懂MySQL数据库分库分表
- 如果数据量过大,大家一般会分库分表。分库需要注意的内容比较少,但分表需要注意的内容就多了。工作这几年没遇过数据量特别大的业务,那些过亿的数据,因为索引设置合理,单表性能没有影响,所以实战中一直没用过分表。最近手里有个项目,预估数据量会很大,分表方案是选项之一,趁着这次机会,把分表的内容整理一下。这次要讲的主要是水平分库分表,其它种类的分库、分表比较容易理解。后面如果不详细说明
- 【PHP】设计模式的六大原则
- 设计模式的六大原则是指导软件开发设计的核心原则,它们帮助开发人员创建可维护、可扩展和灵活的软件系统。这些原则包括: 单一职责原则(Single Responsibility Principle, SRP):一个类应该只有一个引起它变化的原因。这有助于减少类与类之间的耦合,提高类的内聚性和可读性。 开闭原则(Open-Closed Principle, OCP):软件实体(如类、
- 【PHP】rmdir如何强制删除
- php rmdir强制删除的方法:首先判断目录是否存在;然后打开目录返回目录资源,并判断是否成功;接着遍历目录,读出目录中的文件或文件夹;最后使用“rmdir($directory);”方法删除空目录即可。php rmdir使用递归函数删除非空目录我们大家都知道,php rmdir()函数用于删除空目录,但如果要删除非空目录,我们必须将非空目录中的文件或子目录删除,本文章向大家介绍php如何使用递归函数删除非空目录,需要的朋友可以参考一下。首先向大家介绍一下rmdir()函数。ph
- 【PHP】PHP开发中如何使用Nginx实现负载均衡
- 在现代web应用开发中,高并发访问是一个必须要面对的挑战。负载均衡是解决这个问题的一种有效的方案。在php开发中,使用nginx实现负载均衡是一个非常常见的方法。本文将详细介绍如何在php开发中使用nginx实现负载均衡。一、Nginx及负载均衡的基本概念NginxNginx是一款轻量级的高性能的web服务器和反向代理服务器。它的出现解决了Apache这样的传统web服务器在高并发访问下的性能瓶颈。Nginx具有极高的性能、稳定性和安全性,并且支持大量的并发连接。负载均衡负载均衡是一种将网络流量
- 【PHP】thinkphp合理使用数据备份与恢复功能
- ThinkPHP是一款开源的PHP开发框架,具有代码简洁、易于扩展等优点,被众多开发者广泛使用。在开发过程中,数据备份与恢复是一项十分重要的工作。本文将从几个方面介绍在使用ThinkPHP开发时合理使用数据备份与恢复功能的注意事项。首先,建议在开发过程中定期进行数据备份。数据备份可以防止数据丢失或损坏造成的不可恢复性。在ThinkPHP中,可以使用数据库备份与恢复的命令行工具来进行备份,具体操作如下:打开命令行终端,进入到ThinkPHP项目根目录下的thinkphp目录;输入ph
- 【PHP】PHP8如何通过Sanitize Filters来增强应用程序的安全性
- PHP是一门广泛应用于Web开发的脚本语言,而安全性一直是Web应用程序开发者需要关注的重要问题。PHP8提供了一种称为Sanitize Filters的机制,通过对用户输入进行过滤和清理,可以增强应用程序的安全性。本文将详细介绍PHP8中Sanitize Filters的使用方法,并提供一些具体的代码示例,帮助开发者更好地了解如何应用这一特性。首先,让我们来了解一下Sanitize Filters是什么。Sanitize Filters是一组用于过滤和清理用户输入数据的PHP函数,可以帮助开发
栏目分类全部>