我正在尝试在运行的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