微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

协程Coroutine一

协程(Coroutine)(一)

     在使用easyswoole框架做开发的时候,经常需要使用到协程的并发查询。作为从传统fpm模式转到swoole内存常驻模式的PHPer,还是有一点吃力的。但是还是要迎刃而上,要想把协程用好,就先要把它弄清楚。学习过程中参考了《easyswoole官方文档》《swoole官方文档》

一、概念

      协程不是进程或线程,一个程序可以包含多个协程,可以对比于一个进程包含多个线程。多个线程相对独立,有自己的上下文,切换受系统控制;而协程也相对独立,有自己的上下文,但是其切换由自己控制。

因此,协程可以说就是用户态的线程。内核态的线程是由操作系统来进行调度的,但是用户态的线程不是由操作系统来调度的,而是由程序员来调度的,是在用户态的。

二、协程调度

      用户的每个请求都会创建一个协程,请求结束后协程结束,如果同时有成千上万的并发请求,某一时刻某个进程内部会存在成千上万的协程,那么 cpu 资源是有限的,到底执行哪个协程的代码?决定到底让 cpu 执行哪个协程的代码决断过程就是协程调度

      1)首先,在执行某个协程代码的过程中发现这行代码遇到了 Co::sleep() 或者产生了网络 IO,例如 MysqL->query(),这肯定是一个耗时的过程,Swoole 就会把这个 MysqL 连接的 fd(事件的句柄)放到 EventLoop

      2)然后让出这个协程的 cpu 给其他协程使用:即 yield(挂起),等待 MysqL 数据返回后就继续执行这个协程:即 resume(恢复)

      3)其次,如果协程的代码中有cpu密集型代码,我们可以开启enable_preemptive_scheduler,Swoole 会强行让这个协程让出 cpu

三、协程的实现

      1)yield生成器实现 (详细原理可查看http://www.PHP20.cn/article/148)

      2)swoole扩展实现

     说明:同时由于底层封装了协程,所以对比传统的 PHP 层协程框架,开发者不需要使用 yield 关键词来标识一个协程 IO 操作,所以不再需要对 yield 的语义进行深入理解以及对每一级的调用修改为 yield,这极大的提高了开发效率

四、协程的生命周期

     协程内的生命周期与普通PHP函数一致,当协程退出后,协程内变量将全部回收.

五、注意事项

1、协程环境

     使用协程容器,才可以创建协程,否则没有协程环境,不能实现协程切换功能.不能用\co::sleep

2、变量使用

     1)在协程中,需要特别注意,不要使用$_GET,$_POST,$GLOBALS等超全局变量,尤其是需要修改变量值并读取时,将造成协程间变量污染.

     2)协程中访问外部变量必须使用use关键字,或者传形参方式,不能引用变量.

     3)如果需要做多协程之间的通信,可使用channel方式通信.

3、缩写

     Go()是\Co::create() 的缩写, 用来创建一个协程, 接受 callback 作为参数, callback 中的代码, 会在这个新建的协程中执行.

     备注: \Swoole\Coroutine 可以简写为 \Co

 

参考链接

https://www.easyswoole.com

https://wiki.swoole.com/#/start/coroutine

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐