PHP多进程之间的通信

作者: 温新

分类: 【PHP基础】

阅读: 1687

时间: 2021-04-18 14:00:32

了解 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(0, 85, 170)">$str</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'进程间的通信'</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)">$pid</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">pcntl_fork</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)">if</span> (<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$pid</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><br></br><span style="box-sizing: border-box;padding-right: 0.1px">   <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$str</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'我是主进程,我修改了信息'</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)">echo</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$str</span>; <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(119, 0, 136)">elseif</span> (<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$pid</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><br></br><span style="box-sizing: border-box;padding-right: 0.1px">   <span style="box-sizing: border-box;color: rgb(119, 0, 136)">echo</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$str</span>;<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(119, 0, 136)">else</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)">echo</span> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'我是主进程,子进程启动失败'</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span>

通过这个案例可以看到,主进程修改了字符串信息,输出也是修改之后的信息。在子进程中,主进程修改的信息并没有影响到子进程。由此可以知道一个情况,多进程中,每个进程之间是无法通信的。

有些时候是需要进程之间相互通信的,有如下几种方法:

  • 管道通信
  • 消息队列通信(使用linux消息队列)
  • 进程信息通信。
  • 套接字通信
  • 第三方通信。使用文件操作,mysql,redis等
  • 共享内存通信,映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。

案例:通过管道实现多进程间通信

注意了,只能在Linux环境中实现

<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(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)">$pipePath</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.pip'</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(119, 0, 136)">if</span> (<span style="box-sizing: border-box;color: rgb(152, 26, 26)">!</span><span style="box-sizing: border-box;color: rgb(51, 0, 170)">file_exists</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$pipePath</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(119, 0, 136)">if</span> (<span style="box-sizing: border-box;color: rgb(152, 26, 26)">!</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">posix_mkfifo</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$pipePath</span>, <span style="box-sizing: border-box;color: rgb(17, 102, 68)">0644</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)">exit</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'创建管道文件失败'</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><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)">$pid</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">pcntl_fork</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)">// pid=0为子进程</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(119, 0, 136)">if</span> (<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$pid</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><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)">$file</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(51, 0, 170)">fopen</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$pipePath</span>,<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'w'</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(119, 0, 136)">while</span> (<span style="box-sizing: border-box;color: rgb(34, 17, 153)">true</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(51, 0, 170)">fwrite</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$file</span>, <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'hello swolle'</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(51, 0, 170)">fclose</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$file</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)">else</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)">$file</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(51, 0, 170)">fopen</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$pipePath</span>,<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'r'</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)">while</span> (<span style="box-sizing: border-box;color: rgb(34, 17, 153)">true</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)">$content</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(51, 0, 170)">fread</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$file</span>,<span style="box-sizing: border-box;color: rgb(17, 102, 68)">40</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)">echo</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$content</span> . <span style="box-sizing: border-box;color: rgb(0, 0, 0)">PHP_EOL</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)">sleep</span>(<span style="box-sizing: border-box;color: rgb(17, 102, 68)">1</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>
请登录后再评论