于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. ubuntu下使用自带的openJDK查看java源码

    如题 Ubuntu自带的OpenJDK仅仅有jre环境,不提供源代码,所以我们还是须要去下载. JDK6:http://download.java.net/openjdk/jdk6/ JDK7:htt ...

  2. c++ cin>>详解

    参考地址:http://www.cnblogs.com/A-Song/archive/2012/01/29/2331204.html 程序的输入都建有一个缓冲区,即输入缓冲区.一次输入过程是这样的,当 ...

  3. Python的包管理

    0.Python的包管理 在刚开始学习Python的时候比较头疼各种包的管理,后来搜到一些Python的包管理工具,比如setuptools, easy_install, pip, distribut ...

  4. WPF换肤之八:创建3D浏览效果

    原文:WPF换肤之八:创建3D浏览效果 上节中,我们展示了WPF中的异步以及界面线程交互的方式,使得应用程序的显示更加的流畅.这节我们主要讲解如何设计一个具有3D浏览效果的天气信息浏览器. 效果显示 ...

  5. 使用装饰器模式动态设置Drawable的ColorFilter

    使用装饰器模式动态设置Drawable的ColorFilter 欢迎各位关注我的新浪微博:微博 转载请标明出处(kifile的博客) 非常多时候我们都希望Android控件点击的时候,有按下效果,选中 ...

  6. python学习笔记之三:字典,当索引不好用时

    字典是python中唯一内建的映射类型.字典中的值并没有特殊的顺序,但是都存储在一个特定的键(key)里.键可以是数字,字符串甚至是元组. 1. 创建和使用字典 字典可以通过下面的方式创建: phon ...

  7. 大爱jQuery,10美女模特有用jQuery/CSS3插入(集成点免费下载)

    整合下载地址:http://download.csdn.net/detail/yangwei19680827/7343001 jQuery真的是一款非常犀利的Javascript框架,利用jQuery ...

  8. 假防病毒软件从电脑移植到了 Android 平台

    以前有位女研究生点击网络钓鱼的链接.随即出现实时扫毒画面的方式,接着呈现了扫毒结果,跑出十余笔病毒数据,记录了被感染的计算机的具体位置,并提示她必须更新防病毒软件,而她在付费两千元后收到"防 ...

  9. 玩转web之json(五)---将表单通过serialize()方法获取的值转成json

    form表单有一个serialize()方法,可以序列化表单的值,但是jquery提供的这个方法会把数据序列化为类似下面的形式: a=1&b=2&c=3&d=4 jquery并 ...

  10. [Windows Phone]解锁、注册Windows Phone实体手机为开发机(Windows 8)

    原文:[Windows Phone]解锁.注册Windows Phone实体手机为开发机(Windows 8) 前言 ? ? 最近要开发Windows Phone(以下简称WP)的手机游戏,由於使用模 ...