PHP管道通信

PHP管道通信

项目所有源码可在https://github.com/huyanping/simple-fork-php找到。simple-fork-php是php多进程编程框架,以下实现的管道队列为框架的一部分。 管道是IPC(进程通信)最古老的的形式;像在shell中我们使用的ls | wc -l统计文件数量,中间的|实际上就是一个无名管道,它能够将ls的标准输出重定向为wc -l的标准输入。 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道。管道单独构成一种独立的文件系统,管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。(有点像队列) 无名管道只能由于有亲缘关系的父子进程之间通信,如果要在不同归属的进程之间通信,则只能使用命名管道。由于命名管道能够实现无名管道的功能,这里我们主要介绍命名管道。 命名管道的作用更像是队列。php提供了posix_mkfifo函数创建命名管道文件,然后可以使用流操作管道文件。 一段简单的代码如下: $pipe = posix_mkfifo(‘/tmp/test.pipe’); $pid = pcntl_fork(); if($pid==0){ fwrite($pipe, ‘test’); sleep(1); }else{ echo fread($pipe, 4); } 上面代码需要注意两个个问题,fread读取时必须指定读取的长度,如果读取到的长度比指定长度要小,则fread会阻塞(下面会介绍无阻塞的方式);另一个问题管道不会持久化数据,任何一方关闭管道都会造成管道内数据的丢失。 我们可以对管道做进一步封装,实现一个先进先出的流式通信组件(无协议): <?php /** * @author Jenner <hypxm@qq.com> * @blog http://www.huyanping.cn * @license https://opensource.org/licenses/MIT MIT * @datetime: 2015/11/24 16:29 */ namespace Jenner\SimpleFork\Queue; class Pipe { /** * @var resource */
Continue reading PHP管道通信