简体   繁体   English

使用 Windows 命名为 Pipe 用于 IPC 的有效方法

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

I am using jna module to connect two processes that both perform FFMPEG commands.我正在使用jna模块连接两个都执行 FFMPEG 命令的进程。 Send SDTOUT of FFMPEG command on the server side to NampedPipe and receive STDIN from that NampedPipe for other FFMPEG command on the Client side.将服务器端的SDTOUT命令的 SDTOUT 发送到 NampedPipe,并从该 NampedPipe 接收STDIN ,用于客户端的其他 FFMPEG 命令。

this is how I capture STDOUT and send into the pipe in server Side:这就是我捕获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);
     }
}

And this is how I capture STDIN and feed it to the Client Side:这就是我捕获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);
}

But I faced two problems:但是我遇到了两个问题:

  1. High CPU usage due to iterating two loops in Server and Client.由于在服务器和客户端中迭代两个循环,CPU 使用率很高。 (find by profiling resources by VisualVM) (通过 VisualVM 分析资源来查找)
  2. Slower operation than just connecting two FFMPEG command with regular |操作比仅使用常规连接两个 FFMPEG 命令更慢| in command prompt.在命令提示符下。 Speed depends on buffer size but large buffer size blocks operation and small buffer size reduce speed further.速度取决于缓冲区大小,但大缓冲区大小会阻止操作,小缓冲区大小会进一步降低速度。

Questions:问题:

  1. Is there any way not to send and receive in chunks of bytes?有没有办法不发送和接收字节块? Just stream STDOUT to the Namedpipe and capture it in Client.只需 stream STDOUT到 Namedpipe 并在客户端中捕获它。 (Eliminate two Loops) (消除两个循环)
  2. If I cant use NampedPipe, is there any other way to Connect two FFMPEG process that runs in different java modules but in the same machine?如果我不能使用 NampedPipe,有没有其他方法可以连接两个在不同 java 模块中但在同一台机器上运行的 FFMPEG 进程?

Thanks谢谢

Seems like you're constantly polling process states stdin on server side without waiting for any events or sleeping the thread.似乎您一直在服务器端轮询进程状态标准输入,而无需等待任何事件或使线程休眠。 Probably you want to take a look here: Concurrent read/write of named pipe in Java (on windows)可能你想看看这里: Concurrent read/write of named pipe in Java (on windows)

Cheers!干杯!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM