Swoole协程并发调用
Swoole协程并发调用实现原理:
- 在
onRequest
中需要并发两个http
请求,可使用go
函数创建 2 个子协程,并发地请求多个URL
; - 并创建一个
chan
,使用use
必报引用语法,传递给子协程; - 主协程循环调用
chan-pop
,等待子协程完成任务,yield
进入挂起状态; - 并发的两个子协程其中某个完成请求时,调用
chan-push
将数据推送给主协程; - 子协程完成
URL
请求后退出,主协程从挂起状态中恢复,继续向下执行调用$response-end
发送响应结果。
第一步:编写代码
文件:d14.php
<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(152, 26, 26)"><?</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Swoole\Coroutine\MySQL</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Swoole\Coroutine\Redis</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 创建HTTP服务器</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$serv</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">new</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Swoole\Http\Server</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"127.0.0.1"</span>, <span style="box-sizing: border-box;color: rgb(17, 102, 68)">9503</span>, <span style="box-sizing: border-box;color: rgb(0, 0, 0)">SWOOLE_BASE</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 监听</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$serv</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">on</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'Request'</span>, <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> (<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$res</span>, <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$resp</span>) {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 创建通道</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$chan</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">new</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">chan</span>(<span style="box-sizing: border-box;color: rgb(17, 102, 68)">2</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 创建协程</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">go</span>(<span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> () <span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> (<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$chan</span>) {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(51, 0, 170)">var_dump</span>(<span style="box-sizing: border-box;color: rgb(51, 0, 170)">time</span>());</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 连接mysql</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$mysql</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">new</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">MySQL</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$mysql</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">connect</span>([</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'host'</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'127.0.0.1'</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'user'</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'root'</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'password'</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'123456'</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'database'</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'test'</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> ]);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$result</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$mysql</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">query</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'select sleep(3)'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 将结果推送给主协程</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$chan</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">push</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$result</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> });</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">go</span>(<span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> () <span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> (<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$chan</span>) {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(51, 0, 170)">var_dump</span>(<span style="box-sizing: border-box;color: rgb(51, 0, 170)">time</span>());</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$redis1</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">new</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Redis</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$redis1</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">connect</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'127.0.0.1'</span>, <span style="box-sizing: border-box;color: rgb(17, 102, 68)">6379</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$result</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$redis1</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">set</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'hello'</span>,<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'swoole'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$chan</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">push</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$result</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> });</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">go</span>(<span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> () <span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> (<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$chan</span>) {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(51, 0, 170)">var_dump</span>(<span style="box-sizing: border-box;color: rgb(51, 0, 170)">time</span>());</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$redis2</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">new</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Redis</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$redis2</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">connect</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'127.0.0.1'</span>, <span style="box-sizing: border-box;color: rgb(17, 102, 68)">6379</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$result</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$redis2</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">get</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'hello'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$chan</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">push</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$result</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> });</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 从通道中读取数据并存入数组</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$results</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> [];</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">for</span> (<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$i</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(17, 102, 68)">0</span>; <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$i</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)"><</span> <span style="box-sizing: border-box;color: rgb(17, 102, 68)">3</span>; <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$i</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">++</span>) {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$results</span>[] <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$chan</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">pop</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 响应请求</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$resp</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(51, 0, 170)">end</span>(<span style="box-sizing: border-box;color: rgb(51, 0, 170)">json_encode</span>([</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'data'</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$results</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'time'</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span> <span style="box-sizing: border-box;color: rgb(51, 0, 170)">time</span>()</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> ]));</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">});</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$serv</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">start</span>();</span>
第二步:运行http服务器
php d14.php
第三步:浏览器中访问
<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">http</span>:<span style="box-sizing: border-box;color: rgb(170, 85, 0)">//192.168.172.130:9503/</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 页面输出结果</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"data"</span>:[<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"swoole"</span>,<span style="box-sizing: border-box;color: rgb(34, 17, 153)">true</span>,[{<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"sleep(3)"</span>:<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"0"</span>}]],<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"time"</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">1619270058</span>}</span>
第四步:查看http服务器
<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">int</span>(<span style="box-sizing: border-box;color: rgb(17, 102, 68)">1619270058</span>)</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">int</span>(<span style="box-sizing: border-box;color: rgb(17, 102, 68)">1619270058</span>)</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">int</span>(<span style="box-sizing: border-box;color: rgb(17, 102, 68)">1619270058</span>)</span>
可以看到打印三个客户端请求时间是一致的,说明它们是并发执行的。
请登录后再评论