在管道stdout上供应的运行过程是无法跟踪的,直到喂食对管道的喂食为止



我正在尝试在运行的Java程序和控制台之间实现命名基于管道的过程间通信。Java程序的内容(test.java(为:

import java.io.*;
public class Test {
    public static void main(String[] args) throws Exception {
        // starts pipe server
        InputStreamReader isReader = new InputStreamReader(System.in);
        BufferedReader bufReader = new BufferedReader(isReader);
        boolean shutdown = false;
        while(!shutdown) {
            String inputStr = bufReader.readLine();
            if(inputStr != null) {
                System.out.println("PONG: "+inputStr);
            }
            Thread.sleep(1000);
        }
    }
}

程序是使用:

编译的
javac Test.java

创建了一个指定的管道:

mkfifo testing

然后,程序作为管道的消费者运行:

java Test < testing

然后,使用控制台,我将ping发送到管道stdin:

echo PING > testing

由Java程序捕获,输出:

PONG: PING

现在,奇怪的问题:每当java程序运行时,直到发送消息到管道,它的过程是无法使用 ps eaux trake 甚至在/proc/中。

这将在Ubuntu(工作计算机(和RHEL(生产服务器(OS上复制。有人知道为什么会发生这种情况吗?

与您的Java程序无关,但是使用了shell,您就可以从中启动它,并以命名管的行为。

program <file之类的命令中,Shell将首先fork()单独的过程,然后通过open() ING file进行重定向,最后execve() CC_5。

如果file是命名的管道/FIFO,则open()将阻塞直到其另一端也打开。因此,您要观察到的行为,直到您 open() fifo的另一端才开始使用Java程序。

您可以通过在读/写模式下打开FIFO轻松解决,这不会阻止,但这意味着放弃检测读者何时关闭管道的能力 - 您的程序永远不会在其stdin上获得EOF

mkfifo testing
java Test 0<>testing

证明它与Java无关。

在这里,在Shell中实现了相同的代码:

shutdown=1
while [ $shutdown -ne 0 ]; do
  read -r inputStr
  if [ -n "$inputStr" ]; then
    echo "PONG: ${inputStr}"
  fi
  sleep 1.000s
done
sh Test.sh < testing

最新更新