# Inter-process communication

Getting one software process to talk to another software process is a delicate balancing act.
It can be a vital function of an application, though, so it's a problem any programmer embarking on a complex project has to solve.
Whether your application needs to kick off a job being handled by someone else's software, or to monitor an action being performed by a peripheral or over a network, or detect a signal from some other source, when your software relies on something outside of its own code to know what to do next or when to do it, you need to think about inter-process communication (IPC).

The UNIX operating system long ago accounted for this, possibly because of an early expectation that software would originate from diverse sources.
Linux, in the same tradition, provides many of the same interfaces for inter-process communication as well as new ones.
The Linux kernel features several means of IPC, and the [util-linux package](https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/) contains the **ipcmk**, **ipcrm**, **ipcs**, and **lsipc** commands for monitoring and managing IPC messages.

## Show IPC information

Before experimenting around with IPC, you should know what IPC facilities are currently employed on your system.
The ``lsipc`` command provides exactly that information, although

```
RESOURCE DESCRIPTION               LIMIT  USED  USE%
MSGMNI   Number of message queues  32000     0 0.00%
MSGMAX   Max size of message (byt.. 8192     -     -
MSGMNB   Default max size of queue 16384     -     -
SHMMNI   Shared memory segments     4096    79 1.93%
SHMALL   Shared memory pages       184[...] 25452 0.00%
SHMMAX   Max size of shared memory 18446744073692774399
SHMMIN   Min size of shared memory     1     -     -
SEMMNI   Number of semaphore ident 32000     0 0.00%
SEMMNS   Total number of semaphore 1024000.. 0 0.00%
SEMMSL   Max semaphores per semap  32000     -     -
SEMOPM   Max number of operations p  500     -     -
SEMVMX   Semaphore max value       32767     -     -
```

You may notice that this sample listing includes three different types of IPC mechanisms, each available in the Linux kernel: messages (MSG), shared memory (SHM), and semaphores (SEM).
You can view current activity in each of those subsystems with the **ipcs** command:

```
$ ipcs

------ Message Queues Creators/Owners ---
msqid     perms     cuid      cgid  [...]

------ Shared Memory Segment Creators/Owners
shmid     perms    cuid    cgid  [...]
557056    700      seth    users [...]
3571713   700      seth    users [...]
2654210   600      seth    users [...]
2457603   700      seth    users [...]

------ Semaphore Arrays Creators/Owners ---
semid     perms     cuid      cgid  [...]
```

This shows that there are currently no messages or semaphore arrays, but that there are a number of shared memory segments in use.

There's a simple example you can perform on your system so you can see one of these systems at work.
It involves some C code, so you must have build tools on your system.
The names of the packages you must install in order to be able to build from source code vary depending on your distro, so refer to the documentation for specifics.
For example, on Debian-based distributions, you can learn about build requirements on [wiki.debian.org/BuildingTutorial](https://wiki.debian.org/BuildingTutorial), and on Fedora-based distributions refer to [docs.pagure.org/docs-fedora/installing-software-from-source.html](https://docs.pagure.org/docs-fedora/installing-software-from-source.html).

## Create a message queue

Your system has a default message queue already, but you can create your own using the **ipcmk** command:

```
$ ipcmk --queue
Message queue id: 32764
```

Write a simple IPC message sender, hard-coding the queue ID in for simplicity:

```
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>

struct msgbuffer {
 char text[24];
} message;

int main() {
   int msqid = 32764;
   strcpy(message.text,"opensource.com");
   msgsnd(msqid, &message, sizeof(message), 0);
   printf("Message: %s\n",message.text);
   printf("Queue: %d\n",msqid);
   return 0;
       }
```

Compile the application and run it:

```
$ gcc msgsend.c -o msg.bin
$ ./msg.bin
Message: opensource.com
Queue: 32769
```

You just sent a message to your message queue.
You can verify that with the **ipcs** command, using the ``--queue`` option to limit output to just the message queue:

```
$ ipcs -q

------ Message Queues --------
key        msqid   owner  perms  used-bytes  messages
0x7b341ab9 0       seth   666    0          0
0x72bd8410 32764   seth   644    24         1
```

You can also retrieve those messages:

```
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>

struct msgbuffer {
   char text[24];
} message;

int main() {
   int msqid = 32764;
   msgrcv(msqid, &message, sizeof(message),0,0);
   printf("\nQueue: %d\n",msqid);
   printf("Got this message: %s\n", message.text);
   msgctl(msqid,IPC_RMID,NULL);
   return 0;
```

Compile and run:

```
$ gcc get.c -o get.bin
$ ./get.bin

Queue: 32764
Got this message: opensource.com
```

## Download the ebook

This introduction is just one example of implementing lessons from Marty Kalin's [A guide to inter-process communication in Linux](https://opensource.com/downloads/guide-inter-process-communication-linux), the latest free (and Creative Commons) downloadable ebook from opensource.com.
In just a few short lessons, you learn about POSIX methods of IPC, from message queues, shared memory and semaphores, sockets, signals, and much more.
Sit down with Marty's book, and you'll emerge a better-informed programmer, but this isn't just for seasoned coders.
If all you ever write are shell scripts, there's plenty of practical knowledge about pipes (named and unnamed) and shared files, as well as important concepts you need to know when you use a shared file or an external message queue.
If you're interested in making great software that's written to be dynamic and system-aware, you need to know about IPC.
Let this book be your guide.