【PHP】PHP8.1 Fiber交叉执行多任务
CrazyPanda发表于:2024-01-06 22:26:24浏览:321次
大家的电脑应该都是大等于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】Permission denied怎么解决
- Permission denied的解决方法:1、确保当前用户具有足够的权限来执行该操作;2、如果当前用户没有足够的权限,可以尝试更改文件或目录的权限;3、如果当前用户不是管理员或没有足够的权限,可以尝试使用管理员权限来执行操作;4、可以尝试更改文件系统属性,以便允许写入操作;5、可以尝试释放磁盘空间,以便有足够的空间来执行操作;6、检查文件是否被其他进程占用。当我们遇到Permission denied这样的错误提示时,这通常意味着我们没有足够的权限来执行某个操作。解决Permiss
- 【PHP】thinkphp利用缓存提高数据库查询性能
- ThinkPHP是一款十分受欢迎的PHP框架,它提供了许多便捷的功能和优化的设计,使得开发者可以更高效地进行Web应用程序的开发。其中,利用缓存提高数据库查询性能是一个常见的优化手段。本文将分享一些关于如何在ThinkPHP中利用缓存提高数据库查询性能的经验。一、什么是缓存?缓存是指将经常查询的数据存储在快速访问的存储介质中,以提高数据的访问速度。在Web应用程序中,数据库是最常用的数据存储介质之一。而经常查询数据库会带来一定的性能压力。因此,利用缓存可以避免频繁地查询数据库,从而提高
- 【PHP】关于bug率计算和它的实际意义
- 问题1:bug率有什么作用?my opion:用处有很多,需要具体情况具体分析,不过主要作用一般是来评价工作产品的质量。如果bug率较高,说明系统质量较差,需要大量的返工。项目经理就需要做好缺陷分析(缺陷的类型、分布、严重程度等),找出原因,以便做好下一阶段的缺陷预防工作。除此之外,还可以结合其它方面的信息,判断是否一些工作不充分。譬如,如果缺陷密度过低,有两个原因:可能工作产品质量确实高;也可能评审或测试不充分,更多的缺陷没有发现。在某些公司,bug率也作为项目度量考核的一项指标。问题2:bu
- 【PHP】Your requirements could not be resolved to an installable set of packages.
- 执行composer install遇到错误:Your requirements could not be resolved to an installable set of packages. 这是因为不匹配composer.json要求的版本,错误代码如下。Your requirements could not be resolved to an installable set of
- 【PHP】ThinkPHP如何防止SQL注入攻击
- 在ThinkPHP中,参数绑定是一种安全的方式,用于处理用户输入,特别是在构建数据库查询时。参数绑定可以防止SQL注入攻击,因为绑定的参数会被自动转义,而不是直接插入到SQL语句中。以下是在ThinkPHP中使用参数绑定的一些建议。1. 控制器中的参数绑定:在控制器中,可以使用bind方法进行参数绑定。以下是一个简单的示例:public function index($id) { $result = Db::
- 【PHP】PHP 框架中大型项目代码维护挑战与解决方法
- 在大型 php 项目中,代码维护面临主要挑战,包括依赖管理、代码重构、代码风格和文档。解决方法包括:使用依赖项管理器管理版本冲突。使用unittest框架在重构时保持代码完整性。建立并强制执行代码风格指南。建立文档策略并使用phpdoc生成文档。PHP 框架中大型项目代码维护挑战与解决方法在大型 PHP 项目中,代码维护可能是一个艰巨的任务。随着项目规模的增长,代码库会变得庞大且复杂,从而难以管理和更新。以下是 PHP 框架中代码维护面临的主要挑战以及解决这些挑战的一些方法:挑战 1:依赖管理依
- 【PHP】7个php字符串处理函数有哪些
- 7个php字符串处理函数有strlen()、strpos()、substr()、str_replace()、strtolower()、strtoupper()、trim()等。详细介绍:1、strlen(),用于获取字符串的长度;2、strpos(),用于查找字符串中的特定子串,返回第一次出现位置;3、substr(),用于获取字符串的子串;4、str_replace()等等。本教程操作系统:Windows10系统、PHP8.1.3版本、Dell G3电脑。在PHP中,有许多可以用于字
- 【PHP】CI,ThinkPHP,YII,Laravel框架比较
- 用过其中的yii TP CI框架。大概整理了这些框架的优点和缺点,有些错误的地方还希望大家指正。各个框架各有所长,针对的应用场景不同。一、Ci框架推崇简单就是美这一原则,没有花哨的设计模式,没有华丽的对象结构,一切就是那么简单。优点:框架的入门槛很低,极易学,极易用,框架很小,静态化非常容易配置简单,全部的配置使用php脚本来配置,执行效率高缺点:架构略简单,只能满足小型应用,略微不太能够满足中型应用需要大型项目扩展能力差,有些功能需要自己写扩展数据库类的扩展 ci给用户提供了一个名为call_
栏目分类全部>