swoole协程之channel
php
swoole
字数统计: 512(字)
阅读时长: 2(分)
前言
php业务场景中,我们在多个进程之间的通信一般会通过redis内存缓存来达到效果 在协程间的通信,我们可以使用Channel来实现,在类比php多进程处理的时候,可以将Channel类比成redis的队列
Channel特点
与容量有关
如果channel未满,push不阻塞,如果已满,push让出控制流;
如果channel为空,pop让出控制流
demo代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| <?php
$chan = new \Swoole\Coroutine\Channel(15); function t4(\Swoole\Coroutine\Channel $chan) { Co::sleep(0.005); $chan->push([__METHOD__=>__LINE__]); }
function t5(\Swoole\Coroutine\Channel $chan) { Co::sleep(0.005); $chan->push([__METHOD__=>__LINE__]); }
function t6(\Swoole\Coroutine\Channel $chan) { Co::sleep(0.005); $chan->push([__METHOD__=>__LINE__]); }
go("t4", $chan); go("t5", $chan); go("t6", $chan);
go(function() use($chan) { // chan元素个数 $chanNum = 3; while($chanNum>0) { $item = $chan->pop(); var_dump($item); $chanNum --; } });
|
代码分析
角色说明
- 3个生产者协程 (t4、t5、t6)
- 1个消费者协程 (c1)
代码执行
- t4 协程中#1,遇到
Co::sleep() ,让出控制流,挂起(#3、#5 同理)。
- c1开始执行,while循环为真,执行
channel::pop()
- 可能情况:
#8中可能情况1:channel为空,c1让出控制流,挂起;
#8中可能情况2:channel非空,pop弹出数据,while循环继续
- 如果 while 为假,则结束,c1 流量结束
- 如果 while 为真,则进入
channel::pop() 流程,t4 恢复执行(t4、t5、t6 的 sleep 时间相同,因此都有可能线恢复执行,但是统一时刻只有有一个恢复,这里以 t4 为例)。此时 t4 的 channel 写入数据,那么 channel 非空。此时控制流发生变化,消费者协程 c1 恢复执行。c1 协程运行直到让出控制流或者结束。