二十五、Swoole 基础学习笔记 - Swoole Process 管道通信

作者: 温新

分类: 【Swoole 系列】

阅读: 719

时间: 2023-03-13 11:54:55

hi,我是温新,一名PHPer

文章基于 Swoole 5.0.1 版本编写。

学习目标:学习 Process 进程间通信多进程的使用

说明:本篇文章结合官方文档编写及参考网络资料编写,虽非全部原创,但也是结合了自己的理解,若转载请附带本文 URL,编写不易,持续编写更不易,谢谢!

管道通信

进程间的通信就是两个进程之间进行数据交换,管道是 Linux 进程间通信的方式之一。

所谓管道,是指用于连接一个读进程和一个写进程以实现他们之间的通信的一个共享文件。Linux下一切皆文件,所以本质上看管道也是一种文件,但又有所不同,就像是一块固定大小的缓冲区。

管道通信的过程就是:写进程将消息写入管道,读进程在将消息读出来,完成通信。

管道的局限性:

  • 1、它是半双工的,即数据一个管道上的数据只能在一个方向上流动,如果要实现双向通信,就必须在两个进程之间建立两个管道。也就是数据单向流动,一端写,一端读;
  • 2、管道只能在具有公共祖先的两个进程之间使用。

pipe 通信基础案例

<span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><?php</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">// <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">24</span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">-swoole-process-pipe-1</span>.php</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$process</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> new Swoole\Process(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'process_callback'</span>, <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">true</span>);</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> process_callback(<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$worker</span>) {</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    // 将数据写入管道</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$worker</span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">-</span>>write(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'pipe message'</span>);</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">}</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$process</span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">-</span>>start();</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">// 读取管道中的数据</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(232, 191, 106) !important">echo</span> <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'管道信息:'</span> . <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$process</span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">-</span>>read();</span>

多进程执行任务

该案例将模拟多个进程读取网页数据

<span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important"><?</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">php</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 24-swoole-process-pipe-2.php</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 子进程执行任务</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$workers</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> [];</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 要获取的数据 URL</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$urls</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> [</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'https://baidu.com'</span>,</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'https://qq.com'</span>,</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'https://sina.com.cn'</span>,</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'https://baidu.com?search=php'</span>,</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'https://baidu.com?search=linux'</span>,</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'https://baidu.com?search=laravel'</span>,</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">];</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 创建多个进程用于处理任务</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">for</span> (<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$i</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">0</span>; <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$i</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important"><</span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">6</span>; <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$i</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">++</span>) {</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$process</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">new</span> <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">Swoole\Process</span>(<span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> (<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$worker</span>) <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">use</span> (<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$i</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$urls</span>) {</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">echo</span> <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'子进程 '</span> . <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$worker</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">pid</span> . <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">' 执行 '</span> . <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$urls</span>[<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$i</span>] . <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">PHP_EOL</span>;</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 获取远程内容</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$content</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">curl_data</span>(<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$urls</span>[<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$i</span>]);</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 将内容写入管道</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$worker</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">write</span>(<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$content</span>);</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    });</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 子进程 PID</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$pid</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$process</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">start</span>();</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 子进程对象写入数组</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$workers</span>[<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$pid</span>] <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$process</span>;</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">}</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 子进程执行结束后,读取管道中的数据内容</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">foreach</span> (<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$workers</span> <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">as</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$process</span>) {</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 若子进程没有往管道中写入数据,主进程读取时会出现阻塞</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">echo</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$process</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">pid</span> . <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">' '</span> .  <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$process</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">read</span>();</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">}</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">/**</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">* 模拟 CURL 获取内容</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">* </span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">* @param  string $url </span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">* @return string</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">*/</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">curl_data</span>(<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$url</span>) {</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// return file_get_contents($url);</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 延迟 1 秒,模拟远程获取内容所消耗的时间</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(232, 191, 106) !important">sleep</span>(<span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">1</span>);</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">return</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$url</span> . <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">' success '</span> . <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">PHP_EOL</span>;</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">}</span>

输出结果:

<span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$php</span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">24</span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">-swoole-process-pipe-2</span>.php </span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">子进程 <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">79538</span> 执行 https://baidu.com</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">子进程 <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">79539</span> 执行 https://qq.com</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">子进程 <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">79540</span> 执行 https://sina.com.cn</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">子进程 <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">79541</span> 执行 https://baidu.com<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">?search</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span>php</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">子进程 <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">79542</span> 执行 https://baidu.com<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">?search</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span>linux</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">子进程 <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">79543</span> 执行 https://baidu.com<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">?search</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span>laravel</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important"># 读取管道中的数据</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">79538</span> https://baidu.com success </span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">79539</span> https://qq.com success </span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">79540</span> https://sina.com.cn success </span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">79541</span> https://baidu.com<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">?search</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span>php success </span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">79542</span> https://baidu.com<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">?search</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span>linux success </span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">79543</span> https://baidu.com<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">?search</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span>laravel success</span>

本篇文章到此结束,我是温新,下篇文章继续学习 Swoole。

请登录后再评论