28.swoole协程

Swoole协程

swoole的两种命名空间形式

 

Swoole支持两种形式的协程命名空间一种是Swoole\Coroutine,2.2.0以上可使用Co\命名空间短命名简化类名。

 

性能对比

go(function(){

   xxx

})

两者的效果:

   原生的与swoole的协程相比,速度会快3倍左右;

协程的创建在最新版本中默认没有上限;

那么在上面的代码中的话,协程的运行就是任务不断切换

协程并发

协程其实也是阻塞运行的,比如:redis和mysql同时使用协程,去请求数据会出现阻塞现象。。。主要原因是存在于收包(接收redis或者mysql返回数据的时候会存在阻塞的问题)

完成需要4s的时间

这是因为协程收包(获取到的数据)产生的问题;针对于这个问题我们可以通过设置延迟收包解决

请求1->请求2->获取到数据1,获取到数据2

 

最终优化后的效果:2s

 

setDefer延迟收包机制:在收包的时候不急于收包,而是等其他协程结束完成后再收包;

 

发包:就是我们发送一个网络请求

如 :

$mysql2 = new Swoole\Coroutine\MySQL();

$mysql2->connect() 就是发包

 

收包:就是接收结果 

$mysql1->recv()

 

协程通信

协程不允许通信;使用本地内存,不同的进程之间内存是隔离的。只能在同一进程的不同协程内进行push和pop操作

 

这里出现的问题就是,上一个协程因为发生了阻塞,就被挂起;然后另一个请求进来之后就会把之前的$key给切换了;所以当上一个进程进来的时候$key已经被修改了。

协程间的通信可以通过channel方式实现:

 

向通道中写入数据

function Coroutine\Channel->push(mixed $data) : bool;

 

从通道中读取数据。

function Coroutine\Channel->pop() : mixed;

 

对协程调用场景,最常见的“生产者-消费者”事件驱动模型,一个协程负责生产产品并将它们加入队列,另一个负责从队列中取出产品并使用它。

 

 

在方法中的实际使用

For循环是用来接收通道中的信息

灵活处理可变通道个数

 

因为在实际的工作中通道的个数可能就不止一个;是一个可变的方式;所以这里我们需要额外的调整和整理一下;  思路:最为重要的就是记录协程个数,然后根据协程的个数;实现

 

 

 

 

 

 

一键协程化

 

一键协程化:让默认不支持协程原生组件支持协程;简单点说就是让我们不是使用swoole所提供的协程组件,而是用原生的组件比如pdo,redis这些操作,通过swoole的一键协程化,把他们转化为协程;也包括原生的sleep;(感觉很牛逼)

 

如上的代码是没有使用一键协程化;在代码的开始加上如下代码开启一键协程化

Swoole\Runtime::enableCoroutine(true);

 

 

 

对于curl的支持

 

 

Co:yield()方法:可以在不发生io的情况下主动让出

 

co:yield  让出执行权

co:resume 恢复执行权

 

 

uploading.4e448015.gif转存失败重新上传取消

发布了66 篇原创文章 · 获赞 2 · 访问量 4632

猜你喜欢

转载自blog.csdn.net/converoscar/article/details/105359084