原标题:PHP7下的协程实现

什么是协程

先搞清楚,什么是协程。

你可能已经听过『进程』和『线程』这两个概念。

进程就是二进制可执行文件在计算机内存里的一个运行实例,就好比你的.exe文件是个类,进程就是new出来的那个实例。

进程是计算机系统进行资源分配和调度的基本单位(调度单位这里别纠结线程进程的),每个CPU下同一时刻只能处理一个进程。

所谓的并行,只不过是看起来并行,CPU事实上在用很快的速度切换不同的进程。

进程的切换需要进行系统调用,CPU要保存当前进程的各个信息,同时还会使CPUCache被废掉。

所以进程切换不到非不得已就不做。

那么怎么实现『进程切换不到非不得已就不做』呢?

首先进程被切换的条件是:进程执行完毕、分配给进程的CPU时间片结束,系统发生中断需要处理,或者进程等待必要的资源(进程阻塞)等。你想下,前面几种情况自然没有什么话可说,但是如果是在阻塞等待,是不是就浪费了。

其实阻塞的话我们的程序还有其他可执行的地方可以执行,不一定要傻傻的等!

所以就有了线程。

线程简单理解就是一个『微进程』,专门跑一个函数(逻辑流)。

所以我们就可以在编写程序的过程中将可以同时运行的函数用线程来体现了。

线程有两种类型,一种是由内核来管理和调度。

我们说,只要涉及需要内核参与管理调度的,代价都是很大的。这种线程其实也就解决了当一个进程中,某个正在执行的线程遇到阻塞,我们可以调度另外一个可运行的线程来跑,但是还是在同一个进程里,所以没有了进程切换。

还有另外一种线程,他的调度是由程序员自己写程序来管理的,对内核来说不可见。这种线程叫做『用户空间线程』。

协程可以理解就是一种用户空间线程。

协程,有几个特点:

协同,因为是由程序员自己写的调度策略,其通过协作而不是抢占来进行切换

在用户态完成创建,切换和销毁

⚠️ 从编程角度上看,协程的思想本质上就是控制流的主动让出(yield)和恢复(resume)机制

generator经常用来实现协程

说到这里,你应该明白协程的基本概念了吧?

PHP实现协程

一步一步来,从解释概念说起!

可迭代对象

PHP5提供了一种定义对象的方法使其可以通过单元列表来遍历,例如用foreach语句。

你如果要实现一个可迭代对象,你就要实现Iterator接口:

生成器

可以说之前为了拥有一个能够被foreach遍历的对象,你不得不去实现一堆的方法,yield关键字就是为了简化这个过程。

生成器提供了一种更容易的方法来实现简单的对象迭代,相比较定义类实现Iterator接口的方式,性能开销和复杂性大大降低。

记住,一个函数中如果用了yield,他就是一个生成器,直接调用他是没有用的,不能等同于一个函数那样去执行!

所以,yield就是yield,下次谁再说yield是协程,我肯定把你xxxx。

PHP协程

前面介绍协程的时候说了,协程需要程序员自己去编写调度机制,下面我们来看这个机制怎么写。

0)生成器正确使用

既然生成器不能像函数一样直接调用,那么怎么才能调用呢?

方法如下:

foreach他

send($value)

current / next...1)Task实现

Task就是一个任务的抽象,刚刚我们说了协程就是用户空间协程,线程可以理解就是跑一个函数。

所以Task的构造函数中就是接收一个闭包函数,我们命名为coroutine。

2)Scheduler实现

接下来就是Scheduler这个重点核心部分,他扮演着调度员的角色。

这样我们基本就实现了一个协程调度器。

你可以使用下面的代码来测试:

关键说下在哪里能用得到PHP协程。

这样就提高了程序的执行效率。

关于『系统调用』的实现,鸟哥已经讲得很明白,我这里不再说明。

3)协程堆栈

鸟哥文中还有一个协程堆栈的例子。

我们上面说过了,如果在函数中使用了yield,就不能当做函数使用。

所以你在一个协程函数中嵌套另外一个协程函数:

这里的echoTimes是执行不了的!所以就需要协程堆栈。

不过没关系,我们改一改我们刚刚的代码。

把Task中的初始化方法改下,因为我们在运行一个Task的时候,我们要分析出他包含了哪些子协程,然后将子协程用一个堆栈保存。(C语言学的好的同学自然能理解这里,不理解的同学我建议去了解下进程的内存模型是怎么处理函数调用)

当Task->run()的时候,一个循环来分析:

然后我们增加echoTime的结束标示:

然后修改echoTimes:

Task变为:

这样就实现了一个协程堆栈,现在你可以举一反三了。

4)PHP7中yield from关键字

PHP7中增加了yield from,所以我们不需要自己实现携程堆栈,真是太好了。

把Task的构造函数改回去:

echoTimes函数:

task1生成器:

这样,轻松调用子协程。返回搜狐,查看更多

责任编辑:

php7协程通信使用,PHP7下的协程实现相关推荐

  1. python笔记 7-8 进程池 进程通信 迭代器 消息队列 Queue 协程 和正则表达式

    day7 进程 进程池 进程通信 迭代器 消息队列 Queue 作用 用于多个进程间的通信 操作put放入消息(值) put_nowait() 放入值,不等待 如果队满,则报错 get获取消息(值) ...

  2. go 协程和协程通信

    1.go channel channels 是 go 协程routines之间通信的方式,更为安全,为什么这么说,他可以理解为管道, 虽然任何语言可以使用共享变量的方式, 但是更加推荐使用channe ...

  3. python多线程多进程多协程_python 多进程、多线程、协程

    1.python的多线程 多线程就是在同一时刻执行多个不同的程序,然而python中的多线程并不能真正的实现并行,这是由于cpython解释器中的GIL(全局解释器锁)捣的鬼,这把锁保证了同一时刻只有 ...

  4. linux的进程/线程/协程系列1:进程到协程的演化

    linux的进程/线程/协程系列1:进程到协程的演化 前言 摘要: 1. 一些历史:批处理时代 2. 现代操作系统启动过程 3. 进程(process)的出现 4. 线程(thread)与线程池 5. ...

  5. 协程和线程的区别、协程原理与优缺点分析、在Java中使用协程

    文章目录 什么是协程 协程的优点与缺点 协程实现原理. 协程与线程在不同编程语言的实现 在Java中使用协程 Kilim介绍 Kilim整合Java,使用举例 小总结 什么是协程 相对于协程,你可能对 ...

  6. 【PHP7源码分析】PHP7到底有多快,基准测试与特性分析告诉你

    顺风车运营研发团队 王坤 发表至21CTO公众号(https://mp.weixin.qq.com/s/ph...) PHP是一种跨平台开源语言,也是迄今为止最流行的Web开发语言,全球有超过80%的 ...

  7. 协程,又称微线程和纤程

    协程,又称微线程和纤程等,据说源于 Simula 和 Modula-2 语言(我没有深究,有错请指正),现代编程语言基本上都有支持,比如 Lua.ruby 和最新的 Google Go,当然也还有最近 ...

  8. python 协程可以嵌套协程吗_Python线程、协程探究(2)——揭开协程的神秘面纱...

    一.上集回顾 在上一篇中我们主要研究了python的多线程困境,发现多核情况下由于GIL的存在,python的多线程程序无法发挥多线程该有的并行威力.在文章的结尾,我们提出如下需求: 既然python ...

  9. php5.3 with-mysql centos_Centos编译搭建php7让php5.3和php7兼容共存教程

    PHP7版本现在在linux系统中已经开始使用起来了,下面我们来看一篇关于Centos搭建PHP7.0.x让php5.3和php7兼容共存教程,希望下文对各位有帮助. 先安装php5.3 就不说,说C ...

最新文章

  1. vcenter converter 转换xenserver下linux的错误
  2. JAVA学习笔记系列4-Eclipse版本选择
  3. VRRP协议简介与实例配置
  4. R语言数据挖掘2.1.1.1 频繁项集
  5. linuxpython拍照_linux下python抓屏实现方法 -电脑资料
  6. UVA11152 Safe Salutations【计算几何】
  7. BZOJ3244 [Noi2013]树的计数 【数学期望 + 树遍历】
  8. Android自定义弹窗页面,Android编程实现的自定义弹窗(PopupWindow)功能示例
  9. 【回归预测-ELM预测】基于樽海鞘算法结合极限学习机实现风电场功率回归预测附matlab代码
  10. http://hi.baidu.com/%BE%C5%CC%EC%C4%A7%CA%DE/blog/item/9b3263626a75ff49ebf8f808.html
  11. SDNUOJ 1682.easy problem Ⅲ
  12. 最值得看的电影,一生必看的50部电影,您看过几部影
  13. 京东双11准点秒杀脚本
  14. 【MOOS系统安装步骤】
  15. 用python画小鸭_python中的鸭子类型(协议)和接口
  16. Schema Compare 使用手册
  17. linux灯控软件下载,Maize DMX下载
  18. css取消a标签自动换行,css中a元素放长英文字母或者数字自动换行的解决
  19. Go开发的两个小应用
  20. 2021年美容师(初级)考试题及美容师(初级)找解析

热门文章

  1. 剑指OFFER之栈的压入、弹出序列(九度OJ1366)
  2. 认识软件框架的设计原则-- 变与不变分离,创造简美之序
  3. silverlight ListBox 多列图片效果
  4. Agile PLM 9.3.1 安装 checklist
  5. 调试中的一些Python错误
  6. npm run build,start
  7. 详解MySQL字符串函数重复REPEAT()、反转REVERSE()、格式化FORMAT()、返回空格SPACE()函数用法(四)
  8. 【网址收藏】win10环境下安装Docker、Windows安装docker
  9. python3 和python2文件相互转换
  10. 【Java面试题】提取不重复的整数