php如何实现异步调用(php基于协程实现异步的方法分析)
类别:编程学习 浏览量:2189
时间:2022-01-18 01:48:56 php如何实现异步调用
php基于协程实现异步的方法分析本文实例讲述了php基于协程实现异步的方法。分享给大家供大家参考,具体如下:
github上php的协程大部分是根据这篇文章实现的:http://nikic.github.io/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html。
它们最终的结果都是把回调变成了优雅的顺序执行的代码,但还是阻塞的,不是真正的异步。
比如最热门的:https://github.com/recoilphp/recoil
先安装:
|
composer require recoil /recoil |
执行:
|
<?php //recoil.php include __DIR__ . '/vendor/autoload.php' ; use Recoil\React\ReactKernel; $i = 100000; ReactKernel::start(task1()); ReactKernel::start(task2()); function task1(){ global $i ; echo "wait start" . PHP_EOL; while ( $i -- > 0) { yield; } echo "wait end" . PHP_EOL; }; function task2(){ echo "Hello " . PHP_EOL; yield; echo "world!" . PHP_EOL; } |
结果:
wait start
//等待若干秒
wait end
Hello
world!
我本来是想让两个任务并行,结果两个任务变成了串行,中间等待的时间什么事情都干不了。React响应式的编程是严格禁止这种等待的,所以我就参照unity3d的协程自己写了个php版本的。上代码:
|
<?php //Coroutine.php //依赖swoole实现的定时器,也可以用其它方法实现定时器 class Coroutine { //可以根据需要更改定时器间隔,单位ms const TICK_INTERVAL = 1; private $routineList ; private $tickId = -1; public function __construct() { $this ->routineList = []; } public function start(Generator $routine ) { $task = new Task( $routine ); $this ->routineList[] = $task ; $this ->startTick(); } public function stop(Generator $routine ) { foreach ( $this ->routineList as $k => $task ) { if ( $task ->getRoutine() == $routine ){ unset( $this ->routineList[ $k ]); } } } private function startTick() { swoole_timer_tick(self::TICK_INTERVAL, function ( $timerId ){ $this ->tickId = $timerId ; $this ->run(); }); } private function stopTick() { if ( $this ->tickId >= 0) { swoole_timer_clear( $this ->tickId); } } private function run() { if ( empty ( $this ->routineList)){ $this ->stopTick(); return ; } foreach ( $this ->routineList as $k => $task ) { $task ->run(); if ( $task ->isFinished()){ unset( $this ->routineList[ $k ]); } } } } class Task { protected $stack ; protected $routine ; public function __construct(Generator $routine ) { $this ->routine = $routine ; $this ->stack = new SplStack(); } /** * [run 协程调度] * @return [type] [description] */ public function run() { $routine = & $this ->routine; try { if (! $routine ){ return ; } $value = $routine ->current(); //嵌套的协程 if ( $value instanceof Generator) { $this ->stack->push( $routine ); $routine = $value ; return ; } //嵌套的协程返回 if (! $routine ->valid() && ! $this ->stack->isEmpty()) { $routine = $this ->stack->pop(); } $routine ->next(); } catch (Exception $e ) { if ( $this ->stack->isEmpty()) { /* throw the exception */ return ; } } } /** * [isFinished 判断该task是否完成] * @return boolean [description] */ public function isFinished() { return $this ->stack->isEmpty() && ! $this ->routine->valid(); } public function getRoutine() { return $this ->routine; } } |
测试代码:
|
<?php //test.php require 'Coroutine.php' ; $i = 10000; $c = new Coroutine(); $c ->start(task1()); $c ->start(task2()); function task1(){ global $i ; echo "wait start" . PHP_EOL; while ( $i -- > 0) { yield; } echo "wait end" . PHP_EOL; }; function task2(){ echo "Hello " . PHP_EOL; yield; echo "world!" . PHP_EOL; } |
结果:
wait start
Hello
world!
//等待几秒,但不阻塞
wait end
希望本文所述对大家PHP程序设计有所帮助。
原文链接:https://blog.csdn.net/llj1985/article/details/51684210
您可能感兴趣
- phpstorm 菜单如何添加和修改(phpstorm 配置xdebug的示例代码)
- phpstudy的mysql无法启动(Windows系统下解决PhPStudy MySQL启动失败问题)
- phpinclude的使用方法(PHP defined函数的使用图文详解)
- php导出excel使用方法(PHP使用ajax的post方式下载excel文件简单示例)
- php 获取get url(PHP实现获取url地址中顶级域名的方法示例)
- php怎么判断是否有session(PHP中Session ID的实现原理实例分析)
- php 十六进制转换为二进制(PHP实现的62进制转10进制,10进制转62进制函数示例)
- php服务器有哪些(php服务器的系统详解)
- phpstudy安装包打不开(phpStudy访问速度慢和启动失败的解决办法)
- dede模板手机端显示设置(DEDE模板中如何运行php脚本和变量在需要操作数据库字段时)
- thinkphp5 新增模块(Thinkphp5.0框架的Db操作实例分析连接、增删改查、链式操作等)
- php最好的探针(php探针不显示内存解决方法)
- phpstudy怎么修改mysql版本(PhpStudy集成环境升级MySQL数据库版本的方法)
- php与xml文件(PHP读取XML文件的方法实例总结DOMDocument及simplexml方法)
- php数据判断函数有哪些(PHP判断函数是否被定义的方法)
- thinkphp5数据库配置(Thinkphp5框架实现获取数据库数据到视图的方法)
- 王治郅菜鸟赛季已让八一带入正轨,大郅七大经典语录或是成功秘诀(王治郅菜鸟赛季已让八一带入正轨)
- 庆八一,重读经典红色语录,感悟互联网发展硬道理(重读经典红色语录)
- TVB新剧《黯夜守护者》将播,陈展鹏陈炜首次合作探讨人性(TVB新剧黯夜守护者将播)
- 新晋小花被称女版吴卓羲 将取代滕丽名成为TVB新一代御用女警(新晋小花被称女版吴卓羲)
- 艺人吴卓羲10年警察生涯,演足10年阿Sir,系咩玩法(艺人吴卓羲10年警察生涯)
- 菲律宾潜水(菲律宾潜水价格)
热门推荐
- dedecms标签调用原理(DEDECMS栏目页开伪静态的方法apache服务器)
- h5制作支付功能(基于HTML5+tracking.js实现刷脸支付功能)
- php 面向对象与面向过程(php面向对象重点知识分享)
- 阿里云ubuntu系统(阿里云ubuntu16.04如何搭建pptpd服务)
- 织梦cms指定栏目怎么取(织梦CMS后台模板列表按字母排序方法)
- php验证码图解(php/JS实现的生成随机密码验证码功能示例)
- css中有几种样式表(深入浅出学习层叠样式表--css推荐)
- python核心编程和python基础教程(从0开始的Python学习014面向对象编程推荐)
- linux本地文件夹双向同步(linux两台服务器实现自动同步文件)
- exists在sql中用法(详解sql中exists和in的语法与区别)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9