php协程(Coroutine)学习笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Gavin_new/article/details/54603490

PHP5.5中加入了一个新特性—迭代生成器和协程。


一. 什么是协程(Coroutine)?

在协程出现之前,要实现多任务并发,在无OS(操作系统)时代,可以使用状态机的思想对多任务进行拆解,在单进程环境中运行多任务,但是这种模式下需要开发者对每个任务有清晰的了解,也要开发者自行开发与任务相关功能(如任务间的通讯)。

后来出现了OS(操作系统),咱们就开始使用OS提供的进程和线程功能来轻易实现多任务了。在OS中,进程的上下文切换是OS内核控制。但是后来却出现了一个问题,频繁的进程上下文切换导致了OS性能的降低(主要是短时执行消耗小的任务进程)。

为了解决这个问题,开始提出新的概念,就是在同一进程或线程中运行多个任务,这种问题就相当于回到了早期的无OS时代的多任务实现。而现在解决方案称为协程。其本质是,将将任务切换的部分工作从内核转移到应用层。


二. php中协程的基本工具以及基本使用

要实现协程,php给出了两个新东西:生成器和yield关键字。

  1. 什么是生成器?
    生成器继承了实现了迭代器,在php代码中和函数的定义类似,不过内部使用了yield关键字,如:
<?php
function gen(){
    echo "hello gen".PHP_EOL;//step1
    $ret = (yield "gen1");   //step2
    var_dump($ret);  //step3
    $ret = (yield "gen2");   //step4
    var_dump($ret);  //step5
}
?>

使用时,这样子:

<?php
$my_gen = gen();
var_dump($my_gen->current());
var_dump($my_gen->send("main send"));
?>

好了,这样使用代表什么意思呢?
(1)首先$my_gen = gen();这句代码只是实例化一个新的生成器,里面的代码并未执行;
(2)\$my_gen->current();这句代码就执行了生成器里面的step2中的yield “gen1”了,这时代码中断,并且字符串“gen1”被传进了生成器\$my_gen,并且作为current()函数的返回值;
(3)send(“main send”)执行完之后,字符串”main send”被传递进了生成器\$my_gen, 同时生成器作为step2中yield的返回值传递给ret;
(4) 生成器step3执行完后,在step4时,遇到yield就会再次进入中断。


三. 协程的特点

(1)为应用层实现多任务提供了工具;
(2)协程不允许多任务同时执行,要执行其它协程,必须使用关键字yield主动放弃cpu控制权;
(3)协程需要自己写任务管理器,以及任务调度器;
(4)减轻了OS处理零散任务和轻量级任务的负担;

没有更多推荐了,返回首页