在将某些内容馈送到管道 STDIN 之前,无法跟踪以管道 STDOUT 为食的运行进程

我正在尝试在正在运行的 Java 程序和控制台之间实现基于命名 PIPE 的进程间通信。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

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


java Test < testing

然后,使用控制台,我向管道 STDIN 发送 ping:


echo PING > testing

由java程序捕获,输出:


PONG: PING

现在出现了一个奇怪的问题:无论何时运行 java 程序,直到将消息发送到 pipe ,使用ps eaux甚至在/proc/中都无法跟踪其进程。


这在 ubuntu(工作计算机)和 rhel(生产服务器)操作系统上重现。有谁知道为什么会这样?


扬帆大鱼
浏览 96回答 2
2回答

胡说叔叔

这与您的 java 程序无关,但与您从中启动它的 shell 以及命名管道的行为无关。在诸如 之类的命令中program <file,shell 首先会一个单独的进程,然后通过ingfork()执行重定向,最后是.open()fileexecve()program如果file是命名管道/fifo,open()它将阻塞直到它的另一端也被打开。从那里你观察到的行为,你的 java 程序直到你到达open()fifo 的另一端才开始。您可以通过以读/写模式打开 fifo 轻松解决这个问题,这不会阻塞,但这意味着放弃检测读取器何时关闭其管道末端的能力——您的程序将永远不会EOF打开它的标准输入:mkfifo&nbsp;testing java&nbsp;Test&nbsp;0<>testing

冉冉说

为了证明它与Java无关。这里是在 Shell 中实现的相同代码:shutdown=1while [ $shutdown -ne 0 ]; do&nbsp; read -r inputStr&nbsp; if [ -n "$inputStr" ]; then&nbsp; &nbsp; echo "PONG: ${inputStr}"&nbsp; fi&nbsp; sleep 1.000sdonesh Test.sh < testing
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java