php进程通信-PIPE管道通信

举报
仙士可 发表于 2023/06/14 11:40:04 2023/06/14
【摘要】 上一篇文章讲到了php进程通信的进程信号通信方法,本文介绍的是有名管道:管道通信,主要是利用文件,写入以及读取来进行通信的,通俗来讲,就是A进程在1.txt写入1,B进程读取1.txt,就能读取到这个1,这样就通信成功了.当然,php进程管道通信没有这么简单注意:多进程系列文章,都建立在linux环境,php-cli运行模式下一:创建个专属管道的文件: $fifoPath = "tmp/$n...

上一篇文章讲到了php进程通信的进程信号通信方法,本文介绍的是有名管道:

管道通信,主要是利用文件,写入以及读取来进行通信的,

通俗来讲,就是A进程在1.txt写入1,B进程读取1.txt,就能读取到这个1,这样就通信成功了.

当然,php进程管道通信没有这么简单

注意:多进程系列文章,都建立在linux环境,php-cli运行模式下

一:创建个专属管道的文件:

 $fifoPath = "tmp/$name".getmypid() ;//定义文件名
        if (!file_exists($fifoPath)) {
            if (!posix_mkfifo($fifoPath, 0666)) {//posix函数,创建一个特殊的pipe文件
//                error("create new pipe ($name) error.");
                return false;
            }
        } else {
//            error("pipe ($name) has exit.");
            return false;
        }
复制

二:读取数据

$r_pipe = fopen($fifoPath, 'r');//正常读取文件
if ($r_pipe == NULL) {
    return false;
}

$data = fread($r_pipe, 1024);
复制

三:写入数据

$w_pipe = fopen($fifoPath, 'w');//正常操作文件一样打开该管道
if ($w_pipe == NULL) {
    throw new Exception('打开管道错误!');
}

$result = fwrite($w_pipe, $data);//写入文件一样写入数据
复制

四:删除管道

unlink($tfifoPath);//删除文件
复制

五:封装类

<?php

/**
 * Created by PhpStorm.
 * User: tioncico
 * Date: 18-5-21
 * Time: 下午11:51
 */
class Pipe
{
    public $fifoPath;
    private $w_pipe;
    private $r_pipe;

    /**
     * 自动创建一个管道
     *
     * @param string $name 管道名字
     * @param int $mode 管道的权限,默认任何用户组可以读写
     */
    function __construct($name = 'pipe', $mode = 0666)
    {
        $fifoPath = "tmp/$name".getmypid() ;
        if (!file_exists($fifoPath)) {
            if (!posix_mkfifo($fifoPath, $mode)) {
//                error("create new pipe ($name) error.");
                return false;
            }
        } else {
//            error("pipe ($name) has exit.");
            return false;
        }
        $this->fifoPath = $fifoPath;
    }

///////////////////////////////////////////////////
//  写管道函数开始
///////////////////////////////////////////////////
    function open_write()
    {
        $this->w_pipe = fopen($this->fifoPath, 'w');
//        var_dump($this->w_pipe);
        if ($this->w_pipe == NULL) {
            throw new Exception('打开管道错误!');
//            return false;
        }
        return true;
    }

    function write($data)
    {
        return fwrite($this->w_pipe, $data);
    }

    function write_all($data)
    {
        $w_pipe = fopen($this->fifoPath, 'w');
        fwrite($w_pipe, $data);
        fclose($w_pipe);
    }

    function close_write()
    {
        return fclose($this->w_pipe);
    }
/////////////////////////////////////////////////////////
/// 读管道相关函数开始
////////////////////////////////////////////////////////
    function open_read()
    {
        $this->r_pipe = fopen($this->fifoPath, 'r');
        if ($this->r_pipe == NULL) {
//            error("open pipe {$this->fifoPath} for read error.");
            return false;
        }
        return true;
    }

    function read($byte = 1024)
    {
        return fread($this->r_pipe, $byte);
    }

    function read_all()
    {
        $r_pipe = fopen($this->fifoPath, 'r');
        $data   = '';
        while (!feof($r_pipe)) {
            //echo "read one K\n";
            $data .= fread($r_pipe, 1024);
        }
        fclose($r_pipe);
        return $data;
    }

    function close_read()
    {
        return fclose($this->r_pipe);
    }
////////////////////////////////////////////////////

    /**
     * 删除管道
     *
     * @return boolean is success
     */
    function rm_pipe()
    {
        return unlink($this->fifoPath);
    }
}
复制

六:注意事项

1:管道与普通文件有一点非常不同的就是:管道需要先有个进程读取进程,才可以写入,否则按写入模式打开文件时阻塞,以下是测试截图:

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。