zan 是基于PHP协程的网络服务框架,要使用zan框架,首先需要了解php的yield。建议先看一下 在PHP中使用协程实现多任务调度 这篇文章,基础部分内容都只是这篇文章的整理。

yield

yield是php的生成器语法,放在函数内部使用,其效果是return值并且中断此函数的执行。

一个简单的生成值的例子

function gen_one_to_three() {

for ($i = 1; $i <= 3; $i++) {

//注意变量$i的值在不同的yield之间是保持传递的。

yield $i;

}

}

$generator = gen_one_to_three();

foreach ($generator as $value) {

echo "$value\n";

}

?>

以上例程会输出

1

2

3

Generator

一个方法如果内部有yield语法,那么调用这个方法,就会返回一个Generator的对象

function gen_one_to_three() {

for ($i = 1; $i <= 3; $i++) {

//注意变量$i的值在不同的yield之间是保持传递的。

yield $i;

}

}

$generator = gen_one_to_three();

var_dump($generator);

?>

以上例程会输出

class Generator#1 (0) {

}

查看php的官方手册,Generator的类摘要如下

Generator implements Iterator {

/* 方法 */

public mixed current ( void )

public mixed key ( void )

public void next ( void )

public void rewind ( void )

public mixed send ( mixed $value )

public void throw ( Exception $exception )

public bool valid ( void )

public void __wakeup ( void )

}

Iterator

实现了Iterator接口的类,都可以用foreach循环来遍历

Iterator extends Traversable {

/* 方法 */

abstract public mixed current ( void )

abstract public scalar key ( void )

abstract public void next ( void )

abstract public void rewind ( void )

abstract public boolean valid ( void )

}

协程

协程的支持是在迭代生成器的基础上, 增加了可以回送数据给生成器的功能。这就把生成器到调用者的单向通信转变为两者之间的双向通信。下面这个例子说明了如何同时进行接收和发送。

function gen() {

$ret = (yield 'yield1');

var_dump($ret);

$ret = (yield 'yield2');

var_dump($ret);

}

$gen = gen();

var_dump($gen->current()); // string(6) "yield1"

var_dump($gen->send('ret1')); // string(4) "ret1" (the first var_dump in gen)

// string(6) "yield2" (the var_dump of the ->send() return value)

var_dump($gen->send('ret2')); // string(4) "ret2" (again from within gen)

// NULL (the return value of ->send())

?>

这里段代码看起来可能有点费解,调用send之前为什么需要先调用一次current,这个和send的机制有关

Generator::send 『如果当这个方法被调用时,生成器不在 yield 表达式,那么在传入值之前,它会先运行到第一个 yield 表达式。』,接着『向生成器中传入一个值,并且当做 yield 表达式的结果,然后继续执行生成器。』

多任务协作

了解了协程以后,我们就可以基于协程来实现多任务协作了。

多任务协作,有三个比较核心的概念:Task、Coroutine、Scheduler。

Task

首先看一下轻量级的task代码

class Task {

protected $taskId;

protected $coroutine;

protected $sendValue = null;

protected $beforeFirstYield = true;

public function __construct($taskId, Generator $coroutine) {

$this->taskId = $taskId;

$this->coroutine = $coroutine;

}

public function getTaskId() {

return $this->taskId;

}

public function setSendValue($sendValue) {

$this->sendValue = $sendValue;

}

public function run() {

if ($this->beforeFirstYield) {

$this->beforeFirstYield = false;

return $this->coroutine->current();

} else {

$retval = $this->coroutine->send($this->sendValue);

$this->sendValue = null;

return $retval;

}

}

public function isFinished() {

return !$this->coroutine->valid();

}

}

这是Task最简单的版本,只处理单个的yield方法。一个Task处理一个协程。

Scheduler

Scheduler就是调度器。顾名思义,就是调度任务用的。上代码:

class Scheduler {

protected $maxTaskId = 0;

protected $taskMap = []; // taskId => task

protected $taskQueue;

public function __construct() {

$this->taskQueue = new SplQueue();

}

public function newTask(Generator $coroutine) {

$tid = ++$this->maxTaskId;

$task = new Task($tid, $coroutine);

$this->taskMap[$tid] = $task;

$this->schedule($task);

return $tid;

}

public function schedule(Task $task) {

$this->taskQueue->enqueue($task);

}

public function run() {

while (!$this->taskQueue->isEmpty()) {

$task = $this->taskQueue->dequeue();

$task->run();

if ($task->isFinished()) {

unset($this->taskMap[$task->getTaskId()]);

} else {

$this->schedule($task);

}

}

}

}

?>

其实很简单,就是用队列实现了任务调度的功能而已。

参考资料

zan php framework,zan框架入门(一)——协程相关推荐

  1. mysql逻辑架构连接池_GitHub - zzjzzb/ycsocket: 基于swoole的socket框架,支持协程版MySQL、Redis连接池、Actor模型...

    ycsocket 基于 swoole 和 swoole_orm 的 websocket 框架,各位可以自己扩展到 TCP/UDP,HTTP. 在ycsocket 中,采用的是全协程化,全池化的数据库. ...

  2. python协程异步原理_简单介绍Python的Tornado框架中的协程异步实现原理

    Tornado 4.0 已经发布了很长一段时间了, 新版本广泛的应用了协程(Future)特性. 我们目前已经将 Tornado 升级到最新版本, 而且也大量的使用协程特性. 很长时间没有更新博客, ...

  3. 一文快速入门 Kotlin 协程

    一.Kotlin 协程 Kotlin 协程提供了一种全新处理并发的方式,你可以在 Android 平台上使用它来简化异步执行的代码.协程从 Kotlin 1.3 版本开始引入,但这一概念在编程世界诞生 ...

  4. C++高性能协程分布式服务框架设计

    本项目将从零开始搭建出一个基于协程的异步RPC框架. 学习本项目需要有一定的C++,网络,RPC知识 项目地址:zavier-wong/acid: A high performance fiber R ...

  5. Python 协程 asyncio 极简入门与爬虫实战

    在了解了 Python 并发编程的多线程和多进程之后,我们来了解一下基于 asyncio 的异步IO编程--协程 01 协程简介 协程(Coroutine)又称微线程.纤程,协程不是进程或线程,其执行 ...

  6. Kotlin协程入门初级篇

    协程包含很多的功能点,这边只是一些基本功能点的介绍,只适合小白,已经掌握的可以忽略~ 协程入门(一):协程介绍与调用方式 协程入门(二):挂起与取消 协程入门(三):调度器 协程入门(四):启动模式 ...

  7. python asyncio教程_Python 协程模块 asyncio 使用指南

    Python 协程模块 asyncio 使用指南 前面我们通过5 分钟入门 Python 协程了解了什么是协程,协程的优点和缺点和如何在 Python 中实现一个协程.没有看过的同学建议去看看.这篇文 ...

  8. 一文看透 Kotlin 协程本质

    前言 公司开启新项目了,想着准备亮一手 Kotlin 协程应用到项目中去,之前有对 Kotlin 协程的知识进行一定量的学习,以为自己理解协程了,结果--实在拿不出手! 为了更好的加深记忆和理解,更全 ...

  9. 从根上理解高性能、高并发(五):深入操作系统,理解高并发中的协程

    本文原题"程序员应如何理解高并发中的协程",转载请联系作者. 1.系列文章引言 1.1 文章目的 作为即时通讯技术的开发者来说,高性能.高并发相关的技术概念早就了然与胸,什么线程池 ...

最新文章

  1. 某网友发表如此言论:程序员基本都是diao丝,是农村进城务工人员!有资源有关系的都不干程序员!...
  2. 红帽中出现”This system is not registered with RHN”的解决方案
  3. 基于注释的Spring MVC Web应用程序入门
  4. php中符号 的作用是什么意思,PHP中@符号的用途是什么?
  5. ArrayList源码解析
  6. 暂时解决Xmarks无法同步
  7. android距离传感器的应用
  8. Android广播机制Broadcast详解
  9. 笑晕,小米新logo是这么来的
  10. java access group by 用法_详解SQL中Group By的用法
  11. 存在的hive插入数据_往hive表中插入数据以及导出数据
  12. 美颜SDK多少钱一年?视频美颜SDK的价格由哪些因素影响?
  13. H5(HTML)网页制作基础
  14. 【论文笔记】SeqSLAM、Fast-SeqSLAM 和 Bow、Incremental Bow、DBoW2、ORB-SLAM 论文阅读笔记
  15. 《移动App测试实战》读书笔记
  16. Vue-ElementUI教程
  17. Unity粒子系统(5.x)基础(二)
  18. 为什么华为的工程师也要去考公务员???
  19. 文库自由复制(纯文本)
  20. SrpingBoot+Vue实现学生信息管理

热门文章

  1. 第十四章:下载安装WinRAR
  2. Arduino基础学习——第一部分(太极创客)
  3. 刷题记录:牛客NC14662小咪买东西NC15446wyh的物品
  4. 高防服务器维护,高防服务器是如何进行防御的?
  5. python3爬取视频原理_Python3爬虫实战:以爬取豆瓣电影为例
  6. bat移动文件到指定文件夹
  7. APT60DQ60BG ASEMI超快软恢复整流二极管
  8. mysql社工库搭建教程_社工库的搭建思路与代码实现
  9. 大龄宝妈上岸谷歌——竟“抛夫弃子”
  10. 电子战技术基础知识简介