Four Ways of Inter Process Messaging

Well done! You have your first Linux program running. Now you are ready to code the second one but stop! You noticed that they have to communicate and send/receive messages. At that moment, I will tell you about four possible ways of Inter Process Communication on Linux 😎

Shared Memory

On a Linux, the easiest way of communicating to another process is via shared memory. Operating system creates a special file for you and all the processes that wants to communicate to each other only have to access that file. Yet the kernel does much more for you by mapping it into the memory of your process and you only have to use it like any other memory region.

linux shared memory

Creating Shm

It is very simple. The first process has to create shared memory object at a predefined location with the correct permissions. The following line creates a file named /dev/shm/ipc with full permission.

The file descriptor fd will be non-negative on success. The second step is mapping the shared memory area to RAM so that it has an address in memory for reading and writing. Use mmap() for this.

This line maps the file into memory with read and write permissions and returns the address on success.

Messaging over Mapped Shared Memory in C++

I prepared a short demo that sends and receives a simple message made of messageId and messageBody.

You can compile with g++ shared_memory_ipc.cpp -o shared_memory_ipc -lrt -std=c++11 as noted here. In the example code you will find two processes, one is fork()’ed from the parent process, and both share the same memory area to read/write the message. Usage of mutex is important since there is no other mechanism to prevent concurrent access to the data.

First In First Out Pipes

A FIFO object in Linux is a special type of named pipe which provides first-in-first-out buffering which makes it ideal for inter process messaging.

Creating FIFO Messaging Object

First created by calling mkfifo() and later open() it and use it for read() and write() operations.

Messaging over Linux FIFO in C++

The example project creates two processes and the parent process sends messages while the child process receives and prints them. Note that write() is non-blocking as long as the FIFO has space but read() blocks the current thread. Thats why I create an alarm(1) that creates SIGALRM every second to interrupt ongoing or blocking system calls.

Please compile with g++ linux_fifo_ipc.cpp -o linux_fifo_ipc -std=c++11 command.

Unix Domain Socket

The most complex but the most professional way of Linux IPC is socket communication. Unix Domain Socket is not so different than server/client network socket communication but it is intended for local file system use. I will only cover the basics here to showcase its usage.

Creating a Unix Domain Socket

The socket is created just like a file in Linux returning a file handle.

Socket file path is passed with sockaddr_un struct. Here I use file named socket.

Connected Server-Client Messaging

Server Side

The server is responsible for socket binding. This will create the socket file on the disk.

Later the server starts listening, allowing multiple connections and accepts connections to serve them.

Now the returned object from accept() is a new file descriptor for read() and write() operations between the server and the newly connected client. If the server is intended to serve multiple connections, it is a good practice to fork() and serve in the child process while the parent process can accept other clients. For IPC purpose, this is rarely necessary.

Client Side

Clients has to create socket and connect to a server. Rest of the operation is read() and write() just like any other file operation. To close the connection use shutdown() function.

IPC Example via Unix Domain Socket in C++

Here is a short example which summarizes the above concept.

The client connects to the server and sends timestamp but also the server can send data back. The above code compiles with g++ domain_socket_ipc.cpp -o domain_socket_ipc -std=c++11 command.

Connectionless Datagram Messaging

Different than the above approach, here there is no connection and let’s say no server/client. One of the pairs has to bind() the socket and that is the only difference between them. If you are messaging full-duplex, be careful not to read the messages that you have sent yourself (take a look at MSG_PEEK flag).

Simple IPC Unix Domain Socket Messaging in C++

This is much simpler than the connected method I mentioned above. Using sendto() and recvfrom() methods, you can pass messages between processes. I won’t call the processes server and client instead they have nearly identical roles.

Compile with g++ socket_datagram_ipc.cpp -o socket_datagram_ipc -std=c++11 command.

Final Words

I tried to show very basic examples but the IPC topic is huge. Keep this as a starting point and refer to here for shared memory, here for named pipes and here for unix domain socket messaging. Try hard 👍