为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

扬帆大鱼 2023-04-26 16:07:02
我正在尝试在正在运行的 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(生产服务器)操作系统上重现。有谁知道为什么会这样?
查看完整描述

2 回答

?
胡说叔叔

TA贡献1804条经验 获得超8个赞

这与您的 java 程序无关,但与您从中启动它的 shell 以及命名管道的行为无关。

在诸如 之类的命令中program <file,shell 首先会一个单独的进程,然后通过ingfork()执行重定向,最后是.open()fileexecve()program

如果file是命名管道/fifo,open()它将阻塞直到它的另一端也被打开。从那里你观察到的行为,你的 java 程序直到你到达open()fifo 的另一端才开始。

您可以通过以读/写模式打开 fifo 轻松解决这个问题,这不会阻塞,但这意味着放弃检测读取器何时关闭其管道末端的能力——您的程序将永远不会EOF打开它的标准输入:

mkfifo testing
java Test 0<>testing


查看完整回答
反对 回复 2023-04-26
?
冉冉说

TA贡献1877条经验 获得超1个赞

为了证明它与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


查看完整回答
反对 回复 2023-04-26
  • 2 回答
  • 0 关注
  • 95 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信