You have a number of options. Since you are using Linux you could use UNIX domain sockets. Or, you could serialise the data as ASCII or JSon or some other format and feed it through a pipe, SHM (shared memory segment), message queue, DBUS or similar. It's worth thinking about what sort of data you have, as these IPC mechanisms have different performance characteristics. There's a draft USENIX paper with a good analysis of the various trade-offs that is worth reading.

Since you say (in the comments to this answer) that you prefer to use SHM, here are some code samples to start you off. Using the Python posix_ipc library:

import posix_ipc # POSIX-specific IPC
import mmap      # From Python stdlib

class SharedMemory(object):
    """Python interface to shared memory. 
    The create argument tells the object to create a new SHM object,
    rather than attaching to an existing one.
    """

    def __init__(self, name, size=posix_ipc.PAGE_SIZE, create=True):
        self.name = name
        self.size = size
        if create:
            memory = posix_ipc.SharedMemory(self.name, posix_ipc.O_CREX,
                                            size=self.size)
        else:
            memory = posix_ipc.SharedMemory(self.name)
        self.mapfile = mmap.mmap(memory.fd, memory.size)
        os.close(memory.fd)
        return

    def put(self, item):
        """Put item in shared memory.
        """
        # TODO: Deal with the case where len(item) > size(self.mapfile)
        # TODO: Guard this method with a named semaphore
        self.mapfile.seek(0)
        pickle.dump(item, self.mapfile, protocol=2)
        return

    def get(self):
        """Get a Python object from shared memory.
        """
        # TODO: Deal with the case where len(item) > size(self.mapfile)
        # TODO: Guard this method with a named semaphore
        self.mapfile.seek(0)
        return pickle.load(self.mapfile)

    def __del__(self):
        try:
            self.mapfile.close()
            memory = posix_ipc.SharedMemory(self.name)
            memory.unlink()
        except:
            pass
        return    

For the Java side you want to create the same class, despite what I said in the comments JTux seems to provide the equivalent functionality and the API you need is in UPosixIPC class.

The code below is an outline of the sort of thing you need to implement. However, there are several things missing -- exception handling is the obvious one, also some flags (find them in UConstant), and you'll want to add in a semaphore to guard the put / get methods. However, this should set you on the right track. Remember that an mmap or memory-mapped file is a file-like interface to a segment of RAM. So, you can use its file descriptor as if it were the fd of a normal file.

import jtux.*;

class SHM {

    private String name;
    private int size;
    private long semaphore;
    private long mapfile; // File descriptor for mmap file

    /* Lookup flags and perms in your system docs */
    public SHM(String name, int size, boolean create, int flags, int perms) {
        this.name = name;
        this.size = size;
        int shm;
        if (create) {
            flags = flags | UConstant.O_CREAT;
            shm = UPosixIPC.shm_open(name, flags, UConstant.O_RDWR);
        } else {
            shm = UPosixIPC.shm_open(name, flags, UConstant.O_RDWR);
        }
        this.mapfile = UPosixIPC.mmap(..., this.size, ..., flags, shm, 0);
        return;
    }


    public void put(String item) {
        UFile.lseek(this.mapfile(this.mapfile, 0, 0));
        UFile.write(item.getBytes(), this.mapfile);
        return;
    }


    public String get() {    
        UFile.lseek(this.mapfile(this.mapfile, 0, 0));
        byte[] buffer = new byte[this.size];
        UFile.read(this.mapfile, buffer, buffer.length);
        return new String(buffer);
    }


    public void finalize() {
        UPosix.shm_unlink(this.name);
        UPosix.munmap(this.mapfile, this.size);
    }

}
Answer from snim2 on Stack Overflow
🌐
GitHub
github.com › sbt › ipcsocket
GitHub - sbt/ipcsocket: IPC: Unix Domain Socket and Windows Named Pipes for Java · GitHub
IPC Socket is a Java wrapper around interprocess communication (IPC) using java.net.ServerSocket and java.net.Socket as the API.
Starred by 54 users
Forked by 16 users
Languages   Java 78.4% | C 15.5% | Scala 6.1%
Top answer
1 of 2
15

You have a number of options. Since you are using Linux you could use UNIX domain sockets. Or, you could serialise the data as ASCII or JSon or some other format and feed it through a pipe, SHM (shared memory segment), message queue, DBUS or similar. It's worth thinking about what sort of data you have, as these IPC mechanisms have different performance characteristics. There's a draft USENIX paper with a good analysis of the various trade-offs that is worth reading.

Since you say (in the comments to this answer) that you prefer to use SHM, here are some code samples to start you off. Using the Python posix_ipc library:

import posix_ipc # POSIX-specific IPC
import mmap      # From Python stdlib

class SharedMemory(object):
    """Python interface to shared memory. 
    The create argument tells the object to create a new SHM object,
    rather than attaching to an existing one.
    """

    def __init__(self, name, size=posix_ipc.PAGE_SIZE, create=True):
        self.name = name
        self.size = size
        if create:
            memory = posix_ipc.SharedMemory(self.name, posix_ipc.O_CREX,
                                            size=self.size)
        else:
            memory = posix_ipc.SharedMemory(self.name)
        self.mapfile = mmap.mmap(memory.fd, memory.size)
        os.close(memory.fd)
        return

    def put(self, item):
        """Put item in shared memory.
        """
        # TODO: Deal with the case where len(item) > size(self.mapfile)
        # TODO: Guard this method with a named semaphore
        self.mapfile.seek(0)
        pickle.dump(item, self.mapfile, protocol=2)
        return

    def get(self):
        """Get a Python object from shared memory.
        """
        # TODO: Deal with the case where len(item) > size(self.mapfile)
        # TODO: Guard this method with a named semaphore
        self.mapfile.seek(0)
        return pickle.load(self.mapfile)

    def __del__(self):
        try:
            self.mapfile.close()
            memory = posix_ipc.SharedMemory(self.name)
            memory.unlink()
        except:
            pass
        return    

For the Java side you want to create the same class, despite what I said in the comments JTux seems to provide the equivalent functionality and the API you need is in UPosixIPC class.

The code below is an outline of the sort of thing you need to implement. However, there are several things missing -- exception handling is the obvious one, also some flags (find them in UConstant), and you'll want to add in a semaphore to guard the put / get methods. However, this should set you on the right track. Remember that an mmap or memory-mapped file is a file-like interface to a segment of RAM. So, you can use its file descriptor as if it were the fd of a normal file.

import jtux.*;

class SHM {

    private String name;
    private int size;
    private long semaphore;
    private long mapfile; // File descriptor for mmap file

    /* Lookup flags and perms in your system docs */
    public SHM(String name, int size, boolean create, int flags, int perms) {
        this.name = name;
        this.size = size;
        int shm;
        if (create) {
            flags = flags | UConstant.O_CREAT;
            shm = UPosixIPC.shm_open(name, flags, UConstant.O_RDWR);
        } else {
            shm = UPosixIPC.shm_open(name, flags, UConstant.O_RDWR);
        }
        this.mapfile = UPosixIPC.mmap(..., this.size, ..., flags, shm, 0);
        return;
    }


    public void put(String item) {
        UFile.lseek(this.mapfile(this.mapfile, 0, 0));
        UFile.write(item.getBytes(), this.mapfile);
        return;
    }


    public String get() {    
        UFile.lseek(this.mapfile(this.mapfile, 0, 0));
        byte[] buffer = new byte[this.size];
        UFile.read(this.mapfile, buffer, buffer.length);
        return new String(buffer);
    }


    public void finalize() {
        UPosix.shm_unlink(this.name);
        UPosix.munmap(this.mapfile, this.size);
    }

}
2 of 2
1

Some thoughts

  • The server is in Java, the client is written in Python.

An odd combination, but is there any reason one cannot call the other sending via stdin, stdout?

  • Socket IPC is implemented below: it takes 50 cycles sending 200 bytes ! This has got to be too high. If I send 2 bytes in 5000 cycles, it takes a lot less time.

Any call to the OS is going to be relatively slow (latency wise). Using shared memory can by pass the kernel. If throughput is you issue, I have found you can reach 1-2 GB/s using sockets if latency isn't such an issue for you.

  • Both processes run on one Linux machine.

Making shared memory ideal.

  • In the real application about 10 calls to client's iFid.write() are made each cycle.

Not sure why this is the case. Why not build a single structure/buffer and write it once. I would use a direct buffer is NIO to minimise latency. Using character translation is pretty expensive, esp if you only need ASCII.

  • This is done on a Linux system.

Should be easy to optimise.

I use shared memory via memory mapped files. This is because I need to record every message for auditing purposes. I get an average latency of around 180 ns round trip sustained for millions of messages, and about 490 ns in a real application.

One advantage of this approach is that if there are short delays, the reader can catch up very quickly with the writer. It also support re-start and replication easily.

This is only implemented in Java, but the principle is simple enough and I am sure it would work in python as well.

https://github.com/peter-lawrey/Java-Chronicle

Discussions

Java IPC w/Sockets - Using Loopback Device - Stack Overflow
So I'm trying to implement socket communication between processes for a project. But I can't seem to connect to any port via the loopback device. Am I missing something here? I've let this run an a... More on stackoverflow.com
🌐 stackoverflow.com
December 2, 2015
java - How to have 2 JVMs talk to one another - Stack Overflow
What you are looking for is inter-process communication. Java provides a simple IPC framework in the form of Java RMI API. There are several other mechanisms for inter-process communication such as pipes, sockets, message queues (these are all concepts, obviously, so there are frameworks that ... More on stackoverflow.com
🌐 stackoverflow.com
How to create IPC through sockets with a Java client and a Python server? - Stack Overflow
I am trying to make two processes communicate through local sockets: a Python server and a Java client. The data I want to pass between both consists of the bytes of a Protobuf object, with variabl... More on stackoverflow.com
🌐 stackoverflow.com
May 10, 2019
What is the best way for IPC in java? - Stack Overflow
I need to communicate between two jar what is the best IPC Communication. ... "It depends" - will the two applications run on the same host? On different hosts within the same local network? On different hosts on a wide area network? How large is your payload? ... There is never a best way to solve a problem. There is only the way which works best for you. When you have two separate processes running on different hosts, you need to communicate via network sockets... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Baeldung
baeldung.com › home › java › java io › inter-process communication methods in java
Inter-Process Communication Methods in Java | Baeldung
January 16, 2024 - The most obvious example of implementing network-based IPC is to use simple network sockets.
🌐
Ru
homes.cs.ru.ac.za › csgw › research › wellspdpta2009.pdf pdf
Interprocess Communication in Java George C. Wells
directly by using sockets, and through higher level abstrac- tions, such as Remote Method Invocation (RMI). Our recent · work has focused on multicore processors, and has led to the · development of systems constructed of multiple processes, rather than threads. The only interprocess communication · (IPC) mechanisms provided by Java in this scenario are the
🌐
SciELO
scielo.org.za › scielo.php
Interprocess communication with Java in a Microsoft Windows Environment
The Java programming language provides a comprehensive set of multithreading programming techniques but currently lacks interprocess communication (IPC) facilities, other than slow socket-based communication mechanisms (which are intended primarily for distributed systems, not interprocess communication on a multicore or multiprocessor system).
Top answer
1 of 1
2

Well I'm not sure what exactly was the cause of the issue, it very well could be the use of a port number < 1024. Also, I eventually came across a great set of encapsulating readers/writers, the DataOutputStream and DataInputStream classes. These provided a much easier solution by providing specific read and write ops based on the object; such as dis.readInt() and dos.writeInt(int n).

Here is the completed and successfully running source code:

package socket_ipc;
import java.net.*;
import java.io.*;
/** Socket Inter-Process Communication.
 * Implements the Producer-Consumer Problem, using Sockets for IPC.
 * @author William Hatfield: CEG-4350-01 Fall 2015
 */
public class Socket_IPC {
    static final int NUMBER_OF_MESSAGES = 100; // number of messages to pass
    static int[] PRODUCED_MSSG = new int[NUMBER_OF_MESSAGES]; // for comparing
    static int[] CONSUMED_MSSG = new int[NUMBER_OF_MESSAGES]; // for comparing
    static final String HOST = "127.0.0.1"; // IP address of loopback device
    static final int PORT = 1234;           // arbitrary port number (local)
    static ServerSocket serverSocket;       // the shared server socket
    private static class Producer extends Thread {
        @Override
        public void run() {
            try {
                Socket toClient = serverSocket.accept();
                DataOutputStream dos = new DataOutputStream(toClient.getOutputStream());
                for (int i = 0; i < NUMBER_OF_MESSAGES; i++) {
                PRODUCED_MSSG[i] = 
                        (int)((Math.random() - .5) * Integer.MAX_VALUE);
                dos.writeInt(PRODUCED_MSSG[i]);
            }
            } catch (IOException ex) {
                System.err.println("Producer Error: " + ex.toString());
            }
        }
    }
    private static class Consumer extends Thread {
        @Override
        public void run() {
            try {
                Socket fromServer = new Socket(HOST, PORT);
                DataInputStream dis = new DataInputStream(fromServer.getInputStream());
                for (int i = 0; i < NUMBER_OF_MESSAGES; i++) {
                CONSUMED_MSSG[i] = dis.readInt();
            }
            } catch (IOException ex) {
                System.err.println("Consumer Error: " + ex.toString());
            }    
        }
    }
    public static void main(String[] args) {
        try {
            serverSocket = new ServerSocket(PORT);
            Producer p = new Producer();    // create the producer thread
            Consumer c = new Consumer();    // create the consumer thread
            p.start();                      // start the producer thread
            c.start();                      // start the consumer thread
            p.join();                       // wait for producer thread
            c.join();                       // wait for consumer thread
        } catch (InterruptedException | IOException ex) { /* handle later */ }
         /* compare produced and consumed data, exit if any match fails */
        for (int i = 0; i < NUMBER_OF_MESSAGES; i++) {
            System.out.print("[" + i + "]: " + PRODUCED_MSSG[i]);
            System.out.println(" == " + CONSUMED_MSSG[i]);
            if (PRODUCED_MSSG[i] != CONSUMED_MSSG[i]) {
                System.out.println("PROCESS SYNC ERROR AT INDEX: " + i);
                System.exit(0);
            }
        }
        /* inform the user that synchroniozation was succesful, then exit */
        System.out.println("SYNC SUCCESFUL!");
    }
}

If there are any improvements you would like to offer, I'm happy to listen. Especially to the die-hard Java coders, I'm sure there's something that goes against the standard Java practice in here!

🌐
GitHub
github.com › desaivaibhavi › inter-process-communication-example
GitHub - desaivaibhavi/inter-process-communication-example: I have implemented a simple broadcasting portal using the ipc concepts and sockets in java. I have also implemented the concept of multithreading. Here the authentication is also implemented. · GitHub
to run the server : java Server 4119 to run the client : java Client localhost 4119 · Here the server takes one parameter, the port number Here the client takes two parameters, the ip and the port number · When the server program is executed, acceptclient continuously listens to accept clients. Once the client makes connection through socket, new thread is created.
Author   desaivaibhavi
Find elsewhere
🌐
ResearchGate
researchgate.net › publication › 321694778_Interprocess_Communication_with_Java_in_a_Microsoft_Windows_Environment
(PDF) Interprocess Communication with Java in a Microsoft Windows Environment
December 9, 2017 - The Java programming language provides a comprehensive set of multithreading programming techniques but currently lacks interprocess communication (IPC) facilities, other than slow socket-based communication mechanisms (which are intended primarily for distributed systems, not interprocess communication on a multicore or multiprocessor system).
🌐
GitHub
github.com › gongzhang › procbridge
GitHub - gongzhang/procbridge: A super-lightweight IPC (Inter-Process Communication) protocol over TCP socket. · GitHub
ProcBridge has been implemented in Java, Python, Node.js, Swift, and C#. If you want to connect two processes and HTTP & RPC are too heavy for your scenario, then ProcBridge will be an ideal choice. Please go to sub-repos for more information. ... Both request and response are encoded into ProcBridge Packets. Those binary packets are sent over TCP socket directly.
Starred by 123 users
Forked by 15 users
🌐
GitHub
github.com › procilon › pipe-ipc-java
GitHub - procilon/pipe-ipc-java: IPC entry point for local non-http interprocess communication · GitHub
IPC entry point for local non-http inter process communication for Java applications. This library will help you to implement the receiving side of inter process communication outside of stdin, stdout and stderr.
Author   procilon
🌐
CodingTechRoom
codingtechroom.com › tutorial › java-java-ipc
Java IPC: A Comprehensive Guide to Inter-Process Communication in Java - CodingTechRoom
Understanding these concepts will help you in building efficient Java applications that require inter-process communication. ... Q. What is Inter-Process Communication (IPC)? A. IPC allows processes to communicate and share data with each other. It can be achieved through various techniques ...
🌐
GitHub
github.com › fizzed › shmemj
GitHub - fizzed/shmemj: Shared memory and Interprocess Communication (IPC) Library for Java · GitHub
Extremely fast and efficient method of IPC (interprocess communication) between Java-to-Java processes or even Java-to-other processes written in different languages. Lightweight wrappers around shared memory APIs in an OS agnostic way · ...
Author   fizzed
🌐
Inside.java
inside.java › 2021 › 02 › 03 › jep380-unix-domain-sockets-channels
JEP-380: Unix domain socket channels - Inside.java
February 3, 2021 - The SocketChannel and ServerSocketChannel APIs provide blocking and multiplexed non-blocking access to TCP/IP sockets. In Java 16, these classes are now extended to support Unix domain (AF_UNIX) sockets for internal IPC within the same system. This post describes how to use the feature and also illustrates some other use cases, such as communication between processes in different Docker containers on the same system…
Top answer
1 of 7
95

Multiple options for IPC:

Socket-Based (Bare-Bones) Networking

  • not necessarily hard, but:
    • might be verbose for not much,
    • might offer more surface for bugs, as you write more code.
  • you could rely on existing frameworks, like Netty

RMI

  • Technically, that's also network communication, but that's transparent for you.

Fully-fledged Message Passing Architectures

  • usually built on either RMI or network communications as well, but with support for complicated conversations and workflows
  • might be too heavy-weight for something simple
  • frameworks like ActiveMQ or JBoss Messaging

Java Management Extensions (JMX)

  • more meant for JVM management and monitoring, but could help to implement what you want if you mostly want to have one process query another for data, or send it some request for an action, if they aren't too complex
  • also works over RMI (amongst other possible protocols)
  • not so simple to wrap your head around at first, but actually rather simple to use

File-sharing / File-locking

  • that's what you're doing right now
  • it's doable, but comes with a lot of problems to handle

Signals

  • You can simply send signals to your other project
  • However, it's fairly limited and requires you to implement a translation layer (it is doable, though, but a rather crazy idea to toy with than anything serious.

Without more details, a bare-bone network-based IPC approach seems the best, as it's the:

  • most extensible (in terms of adding new features and workflows to your
  • most lightweight (in terms of memory footprint for your app)
  • most simple (in terms of design)
  • most educative (in terms of learning how to implement IPC). (as you mentioned "socket is hard" in a comment, and it really is not and should be something you work on)

That being said, based on your example (simply requesting the other process to do an action), JMX could also be good enough for you.

2 of 7
23

I've added a library on github called Mappedbus (http://github.com/caplogic/mappedbus) which enable two (or many more) Java processes/JVMs to communicate by exchanging messages. The library uses a memory mapped file and makes use of fetch-and-add and volatile read/writes to synchronize the different readers and writers. I've measured the throughput between two processes using this library to 40 million messages/s with an average latency of 25 ns for reading/writing a single message.

🌐
Stack Overflow
stackoverflow.com › questions › 56082065 › how-to-create-ipc-through-sockets-with-a-java-client-and-a-python-server
How to create IPC through sockets with a Java client and a Python server? - Stack Overflow
May 10, 2019 - I am trying to make two processes communicate through local sockets: a Python server and a Java client. The data I want to pass between both consists of the bytes of a Protobuf object, with variabl...
🌐
Simon Fraser University
www2.cs.sfu.ca › CourseCentral › 401 › tiko › lecnotes › ch2.pdf pdf
1 Chapter 2: Interprocess Communication Topics: IPC (Inter-Process
send/receive, transient/persistent communication, Mach IPC, Java and Unix sockets. 2.1 Layered Communication Protocols · Level · Layer Name · Protocol examples · 5 · Application · ftp (file transfer), telnet (virtual terminal), http · 4 · Transport ·
🌐
Jackson State University
jsums.edu › nmeghanathan › files › 2019 › 01 › CSC435-Sp2019-Module-2-Socket-Programming-in-Java.pdf pdf
A Tutorial on Socket Programming in Java Natarajan Meghanathan
system-level details. An IPC application programming interface (API) abstracts the details and · intricacies of the system-level facilities and allows the programmer to concentrate on the ... The Socket API is a low-level programming facility for implementing IPC.
🌐
Reddit
reddit.com › r/csharp › q: ipc between java and .net core program?
r/csharp on Reddit: Q: IPC between Java and .NET Core program?
October 3, 2018 -

So, what's the recommended way to implement this? Custom protocol over raw socket [last resort solution], AMQP [seems nice on the C# side with data contracts, etc, but can it work w/o a broker/router], something else...?

Also, it has to work on Linux/osx.