多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] # 特点 协程有以下特点: (1)协程的调度由应用程序调度器控制,调度器由开发应用程序者编写。协程在应用层面,进程和线程在操作系统层面。 (2)协作式的调度方式。由自己交出cpu执行权。 (3)减轻了OS处理零散任务和轻量级任务的负担。 (4)消耗更少的资源 Php支持协程的版本(PHP 5 >= 5.5.0, PHP 7) 第一点,yield表达式两边的括号在PHP7以前不是可选的, 也就是说在PHP5.5和PHP5.6中圆括号是必须的. 第二点,你可能已经注意到调用current()之前没有调用rewind().这是因为生成迭代对象的时候已经隐含地执行了rewind操作. ~~~ function gen() { yield 'foo'; yield 'bar'; } $gen = gen(); var_dump($gen->send('something')); // 如之前提到的在send之前, 当$gen迭代器被创建的时候一个renwind()方法已经被隐式调用 // 所以实际上发生的应该类似: //$gen->rewind(); //var_dump($gen->send('something')); //这样renwind的执行将会导致第一个yield被执行, 并且忽略了他的返回值. //真正当我们调用yield的时候, 我们得到的是第二个yield的值! 导致第一个yield的值被忽略. //string(3) "bar" ~~~ # 生成器 1. 迭代器iterator 将数据集合用对象的方式存储起来,使用foreach遍历迭代器实现数据集合的遍历。 2. 生成器与迭代器 生成器generator实现了迭代器,含有迭代器的方法。generator 是 forward-only 的迭代,在迭代开始后不能 rewind。生成器不能被实例化,也就是直接new。通过含有yield关键字函数返回。在函数里面的yield构成了中断点。 3. yield关键字 可以理解为返回生成器函数的中断点,可以返回数据和向其发送数据。是生成器的关键所在。 4. 生成器与协程 协程的支持是在迭代生成器的基础上, 增加了可以回送数据给生成器的功能(调用者发送数据给被调用的生成器函数). 这就把生成器到调用者的单向通信转变为两者之间的双向通信. 返回生成器的函数中函数体可以理解为一个协程。生成器调用成员函数控制协程的上下文执行 # 代码 yield的根本实现是生成器类,而迭代器类是迭代器接口的实现 ~~~ Generator implements Iterator { public mixed current ( void ) // 返回当前产生的值 public mixed key ( void ) // 返回当前产生的键 public void next ( void ) // 生成器继续执行 public void rewind ( void ) // 重置迭代器,如果迭代已经开始了,这里会抛出一个异常。 // renwind的执行将会导致第一个yield被执行, 并且忽略了他的返回值. public mixed send ( mixed $value ) // 向生成器中传入一个值,并且当做 yield 表达式的结果,然后继续执行生成器。如果当这个方法被调用时,生成器 // 不在 yield 表达式,那么在传入值之前,它会先运行到第一个 yield 表达式。 public void throw ( Exception $exception ) // 向生成器中抛入一个异常 public bool valid ( void ) // 检查迭代器是否被关闭 public void __wakeup ( void ) // 序列化回调,抛出一个异常以表示生成器不能被序列化。 } ~~~ # go的协程 Go调度模型是G(协程)、P(调度器)、M(OS线程)三层构成的。Go系统调用就是同步调用,当前的协程(G)所在的OS线程(M)会被阻塞,但是Go调度器(P)会被剥离出来,寻找空闲或者创建新的OS线程(M)来绑定P,去执行其它等待运行的协程(G)。在Go里面进行大量文件IO操作,会产生大量OS线程(M) # 参考文章 http://www.laruence.com/2015/05/28/3038.html http://www.powerxing.com/php-review-generator/ https://yq.aliyun.com/articles/53673 http://www.php230.com/weixin1409789107.html https://segmentfault.com/a/1190000010576658