跳至主要内容

Java & IPC

在Windows/Unix-like平台中,针对 IPC (Inter-process Communication)提供了许多机制,例如 Semaphore, Pipe, Shared memory等。在Java中,这些强大的能力都受到了限制,由于Java本身是提供Thread机制的,所以线程间是不大需要考虑使用IPC的,但是有时候Java应用程序可能需要同其它的native application进行通信,这种情况下就需要考虑IPC方式了。

Socket当然是可选方案之一,不过很多时候由于需要通信的数据并不多,采用socket就有点算weight solution了。RMI和Socket就不放在考察范围之内。

遗憾的是,根据google查到的资料,并没有发现非常简洁优雅的解决方案——最raw的就是用JNI了,遇到这种需要维护C、C++指针的情况,crash掉整个JVM的bug是必然多发的。查了一些资料,愈发无奈…… 难道真的要靠自己搞定JNI,或是购买成熟的commercial product来解决??



I am familiar and had used many times concurrent threads and "synchronized" in Java. The thing is, I want to share memory between 2 threads/processes , one in Java and one in "C".

There is of course the JNI solution; I am currently using it; the thing is that when you call a JNI method from Java , and there is some problem in the "C" code (like a pointer which is not handled right and ,for example, is incremented so that it points to a non-valid address) it is sometimes difficult to trace. Of course you can use bound checkers and other memory debugging tools, but it is a sometimes cumbersome. Especially , when there is a problem with a pointer as I depicted above, the crash will be sometiomes in the Java part (so it seems to me ) ; As I understand , when you allocate memory in the JNI "C" method, it gets it memory from a memory manager of the "c" compiler , but there is an upper memory layer of Java which controls it somehow. (I am NOT sure about it; memory managers allocation algorithms are complex , and I don't know much about Java memory manager since Sun's code is not an open source ).

If the two threads need only a little in common (lets say one should only pass a string of 10 chars to the second ("C") code, as it is in my case, it seems to me that using shared memory can be a solution (if it is an option at all).

It may be a little less efficemt than using JNI, but it can be easier to maintain/debug.



How do I use Unix pipes with Java?

Java doesn't give you direct access to non-portable capabilities like Unix/Linux pipes. You can still do quite a few things with pipes, for example:

Create a named pipe by invoking the mkfifo utility in a Runtime.exec() method.
Open a named pipe by name - which is just like opening a file.
Run an external process with Runtime.exec() and access its input and output streams via the Process.getInputStream() and Process.getOutputStream() methods.

If none of these solves the problem and you need to get to the pipe() system call, you'll need to write your own JNI code to do it.


评论