簡體   English   中英

使用 Windows 命名為 Pipe 用於 IPC 的有效方法

[英]An efficient way to use Windows Named Pipe for IPC

我正在使用jna模塊連接兩個都執行 FFMPEG 命令的進程。 將服務器端的SDTOUT命令的 SDTOUT 發送到 NampedPipe,並從該 NampedPipe 接收STDIN ,用於客戶端的其他 FFMPEG 命令。

這就是我捕獲STDOUT並將其發送到服務器端的 pipe 的方式:

InputStream out = inputProcess.getInputStream();
byte[] buffer = new byte[maxBufferSize];
while (inputProcess.isAlive()) {
     int no = out.available();
     if (no > 0 && no > maxBufferSize) {
        int n = out.read(buffer, 0,maxBufferSize);
        IntByReference lpNumberOfBytesWritten = new IntByReference(maxBufferSize);
        Kernel32.INSTANCE.WriteFile(pipe, buffer, buffer.length, lpNumberOfBytesWritten, null);
     }
}

這就是我捕獲STDIN並將其提供給客戶端的方式:

OutputStream in = outputProcess.getOutputStream();
while (pipeOpenValue >= 1 && outputProcess.isAlive() && ServerIdState) {
      // read from pipe
      resp = Kernel32.INSTANCE.ReadFile(handle, readBuffer,readBuffer.length, lpNumberOfBytesRead, null);
      // Write to StdIn inputProcess
      if (outputProcess != null) {
          in.write(readBuffer);
          in.flush();
      }
      // check pipe status
      Kernel32.INSTANCE.GetNamedPipeHandleState(handle, null,PipeOpenStatus, null, null, null, 2048);
      pipeOpenValue = PipeOpenStatus.getValue();
      WinDef.ULONGByReference ServerId = new WinDef.ULONGByReference();
      ServerIdState = Kernel32.INSTANCE.GetNamedPipeServerProcessId(handle, ServerId);
}

但是我遇到了兩個問題:

  1. 由於在服務器和客戶端中迭代兩個循環,CPU 使用率很高。 (通過 VisualVM 分析資源來查找)
  2. 操作比僅使用常規連接兩個 FFMPEG 命令更慢| 在命令提示符下。 速度取決於緩沖區大小,但大緩沖區大小會阻止操作,小緩沖區大小會進一步降低速度。

問題:

  1. 有沒有辦法不發送和接收字節塊? 只需 stream STDOUT到 Namedpipe 並在客戶端中捕獲它。 (消除兩個循環)
  2. 如果我不能使用 NampedPipe,有沒有其他方法可以連接兩個在不同 java 模塊中但在同一台機器上運行的 FFMPEG 進程?

謝謝

似乎您一直在服務器端輪詢進程狀態標准輸入,而無需等待任何事件或使線程休眠。 可能你想看看這里: Concurrent read/write of named pipe in Java (on windows)

干杯!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM