首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 多進程管道通信實作:基於 FIFO 命名管道的類封裝

     編輯:PHP 相關知識

PHP 多進程管道通信實作:基於 FIFO 命名管道的類封裝

PHP 多進程協作可透過命名管道實現進程間通信(IPC)。管道本質為先進先出佇列,預設容量 4KB,預設阻塞模式(寫滿阻塞、讀空阻塞),可用 stream_set_blocking 設為非阻塞。

管道通信類

<?php
class Pipe {
    public $fifoPath;
    private $w_pipe;
    private $r_pipe;

    /**
     * 建立命名管道
     * @param string $name 管道名稱
     * @param int $mode 權限(預設 0666)
     */
    public function __construct($name = 'pipe', $mode = 0666) {
        $this->fifoPath = "/tmp/$name." . posix_getpid();
        if (!file_exists($this->fifoPath)) {
            if (!posix_mkfifo($this->fifoPath, $mode)) {
                trigger_error("create pipe ($name) failed", E_USER_ERROR);
                return false;
            }
        } else {
            trigger_error("pipe ($name) already exists", E_USER_WARNING);
            return false;
        }
    }

    // ===== 寫入相關 =====
    public function open_write() {
        $this->w_pipe = fopen($this->fifoPath, 'w');
        return $this->w_pipe !== false;
    }
    public function write($data) {
        return fwrite($this->w_pipe, $data);
    }
    public function write_all($data) {
        $fp = fopen($this->fifoPath, 'w');
        fwrite($fp, $data);
        fclose($fp);
    }
    public function close_write() {
        return fclose($this->w_pipe);
    }

    // ===== 讀取相關 =====
    public function open_read() {
        $this->r_pipe = fopen($this->fifoPath, 'r');
        return $this->r_pipe !== false;
    }
    public function read($byte = 1024) {
        return fread($this->r_pipe, $byte);
    }
    public function read_all() {
        $fp = fopen($this->fifoPath, 'r');
        $data = '';
        while (!feof($fp)) {
            $data .= fread($fp, 1024);
        }
        fclose($fp);
        return $data;
    }
    public function close_read() {
        return fclose($this->r_pipe);
    }

    // 刪除管道
    public function rm_pipe() {
        return unlink($this->fifoPath);
    }
}
?>

使用範例

// 父進程建立管道
$pipe = new Pipe('myipc');
$pid = pcntl_fork();
if ($pid == -1) die('fork failed');
if ($pid == 0) {
    // 子進程:讀取管道
    $pipe->open_read();
    echo "Child received: " . $pipe->read_all() . "\n";
    $pipe->close_read();
    $pipe->rm_pipe();
    exit;
} else {
    // 父進程:寫入管道
    $pipe->open_write();
    $pipe->write("Hello from parent!\n");
    $pipe->close_write();
    pcntl_wait($status);
}

關鍵點

  • 管道路徑放在 /tmp,以 PID 區分,避免衝突。
  • posix_mkfifo 需啟用 POSIX 擴展(Linux/Unix 環境)。
  • 阻塞特性:fopen('w') 會阻塞直到有讀端開啟;fopen('r') 會阻塞直到有寫端開啟。
  • 生產環境建議加入超時、非阻塞模式、資料幀協議(如長度前綴/分隔符)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved