于server其中编程。为了实现异步。通常情况下,需要回调。比例如下面的代码

function send($value) {
$data = process($value);
onReceive($data);
} function onReceive($recv_value) {
var_dump($recv_value);
} function process($value) {
return $value+1;
} $send_value = 1;
send($send_value);


实现的东西非常easy,事实上就是将send_value发送到远端,远端server对其进行加一操作后,发送回来,于是在onReceive中我们能够得到远端server的返回值recv_value。

可是这种代码就会看上去比較支离破碎,尤其是在process其中再次进行远程过程调用的时候。会变得更加难以开发和维护。协程就是为了解决这种问题,使得异步的代码看起来同步化。

以下就是使用php的yield完毕代码调度的演示样例(假设想看懂这段代码。须要首先了解一下php 5.5的新特性generator和yield)

框架代码例如以下:

class CCoroutine {

    /**
*
* @var Generator
*/
public $coroutine; /**
*
* @var miexed null or CCoroutine
*/
public $father; public function __construct($coroutine, $father = null) {
$this->coroutine = $coroutine;
$this->father = $father;
} } class AsyncTask { public $data; public function __construct($data) {
$this->data = $data;
} } abstract class CoroutineScheduler { protected $coroutine = NULL; abstract function send_and_receive($value); public function run($data) {
$co = $this->send_and_receive($data);
$ccoroutine = new CCoroutine($co);
$this->schedule($ccoroutine);
} protected function schedule($ccoroutine) {
$task = $ccoroutine->coroutine->current();
//假设当前值为空,表示这个$ccoroutine应该已经结束了
if (is_null($task)) {
if (is_null($ccoroutine->father)) {
//已经彻底调度结束了--通常是onRecieve方法执行到最后一步了
return;
} else {
//注意,假设执行到这个分支,则表示子生成器没有给父生成器传数据
//子生成器可能是通过引用传递来改变父生成器的变量值
//所以这个时候仅仅要调度父生成器就能够了
$ccoroutine->father->coroutine->next();
$father = $ccoroutine->father;
$this->schedule($father);
unset($ccoroutine);
}
} else {
if (is_object($task) && $task instanceof AsyncTask) {
//当task是异步数据请求的时候,開始处理socket而且将进程熄火在这里
$this->dealTask($task, $ccoroutine);
} elseif (is_object($task) && $task instanceof \Generator) {
//当task是生成器时,表示当前生成器又有了子生成器的调用
$newcc = new CCoroutine($task, $ccoroutine);
$this->schedule($newcc);
} elseif ($ccoroutine->father != null) {
//注意,假设执行到这个分支,则表示在子的生成器里调用了yield $str;这种写法
//我们规定这种写法是在给父生成器传数据,所以当前生成器就会终止调用了转而去调度父生成器
$ccoroutine->father->coroutine->send($task);
$father = $ccoroutine->father;
$this->schedule($father);
unset($ccoroutine);
}
}
} protected function dealTask($task, $ccoroutine) {
$this->coroutine = $ccoroutine;
$this->send($task->data);
} public function send($value) {
$data = $this->process($value);
$this->onReceive($data);
} public function process($value) {
return $value+1;
} protected function onReceive($data) {
$this->coroutine->coroutine->send($data);
$this->schedule($this->coroutine);
} }

框架将 send, onReceive等函数所有都封装好了,使得调用方的代码看起来能够是同步的代码

调用方代码例如以下:

//1. 须要去实现CoroutineScheduler的send_and_receive函数,主要是为了在里面拿到返回值
class Solution extends CoroutineScheduler { public function send_and_receive($data) {
$result = (yield new AsyncTask($data));
var_dump($result); } } //2. 在最外层去调用框架的代码。给出输入參数 $data
$s = new Solution();
$data = 1;
$s->run($data);

版权声明:本文博客原创文章,博客,未经同意,不得转载。

PHP实现协同程序的更多相关文章

  1. Lua 学习笔记(九)协同程序(线程thread)

    协同程序与线程thread差不多,也就是一条执行序列,拥有自己独立的栈.局部变量和命令指针,同时又与其他协同程序共享全局变量和其他大部分东西.从概念上讲线程与协同程序的主要区别在于,一个具有多个线程的 ...

  2. Unity3D协同程序(Coroutine)

    摘要下: 1. coroutine, 中文翻译"协程".这个概念可能有点冷门,不过百度之,说是一种很古老的编程模型了,以前的操作系统里进程调度里用到过,现在操作系统的进程调度都是根 ...

  3. 【转】Unity中的协同程序-使用Promise进行封装(三)

    原文:http://gad.qq.com/program/translateview/7170967 译者:崔国军(飞扬971)    审校:王磊(未来的未来) 在这个系列的最后一部分文章,我们要通过 ...

  4. 【转】Unity中的协同程序-使用Promise进行封装(二)

    原文:http://gad.qq.com/program/translateview/7170970 译者:王磊(未来的未来)    审校:崔国军(飞扬971)   在上一篇文章中,我们的注意力主要是 ...

  5. 【转】Unity中的协同程序-使用Promise进行封装(一)

    原文:http://gad.qq.com/program/translateview/7170767 译者:陈敬凤(nunu)    审校:王磊(未来的未来) 每个Unity的开发者应该都对协同程序非 ...

  6. 【转】关于Unity协同程序(Coroutine)的全面解析

    http://www.unity.5helpyou.com/2658.html 本篇文章我们学习下unity3d中协程Coroutine的的原理及使用 1.什么是协调程序 unity协程是一个能暂停执 ...

  7. Lua中的协同程序 coroutine

    Lua中的协程和多线程很相似,每一个协程有自己的堆栈,自己的局部变量,可以通过yield-resume实现在协程间的切换.不同之处是:Lua协程是非抢占式的多线程,必须手动在不同的协程间切换,且同一时 ...

  8. Unity 中的协同程序

    今天咱就说说,协同程序coroutine.(这文章是在网吧敲的,没有unity,但是所有结论都被跑过,不管你信得过我还是信不过我,都要自己跑一下看看,同时欢迎纠错)先说说啥是协程:协同程序是一个非常让 ...

  9. 9. MonoBehaviour.StartCoroutine 开始协同程序

    function StartCoroutine (routine : IEnumerator) : Coroutine 描述:开始协同程序. 一个协同程序在执行过程中,可以在任意位置使用yield语句 ...

  10. 【笨木头Lua专栏】基础补充08:协同程序之resume-yield间的数据返回

    这次要介绍几个事实上非常easy,可是一定要小心的返回值规则. 笨木头花心贡献,哈?花心?不,是用心~ 转载请注明.原文地址: http://www.benmutou.com/archives/173 ...

随机推荐

  1. SDL2源码分析8:视频显示总结

    ===================================================== SDL源码分析系列文章列表: SDL2源码分析1:初始化(SDL_Init()) SDL2源 ...

  2. 基于CentOS 5.4搭建nginx+php+spawn-fcgi+mysql高性能php平台

    一.安装准备 1.1平台环境: CentOS 5.4 x86_64 GNU/Linux nginx-0.8.21 php-5.2.9 spawn-fcgi-1.6.3 mysql-5.1.34 .2系 ...

  3. 在centos上部署java WEB环境

    题语:偷得浮生半日闲,趁着十一期间,好好的写写随笔来记录自己所学.所践和所得,不足之处,欢迎各位拍砖~~~ 工具:Xftp 5.Xshell 5 一.安装jdk  1. 使用Xftp 5把jdk-8u ...

  4. 开源企业IM-免费企业即时通讯-ENTBOOST V2014.183 Windows版本号正式宣布

    ENTBOOST,VERSION 2014.183 Windows(点击下载)版本号公布.主要添加PC端P2P(点对点)文件传输功能:公布安卓Android手机clientAPP 1.0版本号.公布苹 ...

  5. 第五章_JSTL

    5.1.下载JSTL http://jstl.java.net 5.2.JSTL类库 类别 下属功能 URI 前缀 Core 变量支持 http://java.sun.com/jsp/jstl/cor ...

  6. Excel阅读器NPOI

    什么是NPOI? NPOI 它是 POI 项目的 .NET 版本号. POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. 使用 NPOI 你就能够在没有安装 Office ...

  7. MultiROM for the XIAOMI MI2S/2C/2! (Kexec HardBoot Enabled with Kexec HardBoot Patch!)

    Introduction This is a port of Tassadar's MultiROM, a multi-boot mod for XIAOMI MI2/2S/2C. The main ...

  8. 凝视条件推断浏览器<!--[if !IE]><!--[if IE]><!--[if lt IE 6]><!--[if gte IE 6]>

    <!--[if !IE]><!--> 除IE外可识别 <!--<![endif]--> <!--[if IE]> 所有的IE可识别 <![e ...

  9. 询url包括字符串参数(js高度注意事项)

    以防万一  url="http://write.blog.csdn.net/postedit? id=5&search=ok" function getArgs() { v ...

  10. ORA-00600 [kollasg:client-side tmp lob]

    今天在查看一个库的日志时,发现被ORA-00600 [kollasg:client-side tmp lob] 错误刷屏了. 发生该错误的原因是由于应用那边lob的问题.lob没有被初始化,建议使用E ...