通过 setDefer 机制实现并发编程

以 Redis 和 MySQL 客户端请求为例,使用上述 Swoole\Coroutine\RedisSwoole\Coroutine\MySQL 组件,可以实现异步 Redis 和 MySQL 客户端

协程的 setDefer 机制:绝大部分协程组件都支持 setDefer,该机制可以将请求响应式的接口拆分为两个步骤:先发送数据, 再并发收取响应结果

设置 setDefer(true) 后,通过 Redis 或 MySQL 客户端发起请求,将不再等待服务器返回结果,而是在发送请求之后,立即返回 true。在此之后可以继续发起其他 Redis、MySQL 请求,最后再使用 recv() 方法接收响应内容。

启动http服务端,在客户端访问172.19.0.4:9588,等待几秒,可以看到结果:

前三个时间分别是 mysql、redis1、redis2 三个客户端发起请求的时间,可以看到,尽管 mysql 中会休眠 3 秒,但是通过 defer 机制实现了三个请求的并发执行

通过子协程+通道实现并发编程

除了 setDefer 机制外,Swoole 还支持通过子协程+通道实现并发编程,下面我们通过子协程+通道的方式来改写上面的代码实现

三个子协程之间数据是相互隔离的,所以我们通过 Swoole\Coroutine\Channel (即通道)实现协程之间的数据共享和通信,初始化其缓冲空间为 3

然后通过 use 方式将其引入到子协程中,把响应结果通过 push 方法放到 Channel 里面

接下来在服务端 onRequest 回调函数末尾通过一个循环将 Channel 中的数据通过 pop 方法依次取出来放到数组 $results 中

最后通过 $response->end() 方法将结果以 JSON 格式返回给客户端。

启动http服务端,在客户端访问172.19.0.4:9588,等待几秒,可以看到结果:

由于 MySQL 请求执行耗时最长,所以位置最靠后。在启动服务器的终端,可以看到打印出的三个客户端请求时间,完全一致,说明它们是并发执行的


REFERENCE


0 条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注