Linux Kernel

LinuxIPCMechanisms

IPC stands for “Inter-Process Communication”. As the name suggests, it refers to the methods through which different processes can communicate with each other. Linux defines the three IPC mechanisms:

  1. Shared Memory
  2. Semaphores
  3. Message Queues

We will go through all three of these mechanisms with examples.

Description

There are three Inter-Process Communication mechanisms used by the Linux kernel. As we are aware, Linux defines a process as a logical execution instance of the program, and for security reason, all processes have their own address space. None of the processes are allowed to access other process address. So just imagine of a situation where one process wants to share the data with other process. How this can be done? The answer to this question is the IPC mechanism offered by the Linux kernel. One process sends data to the kernel data structures, and then the receiver process retrieves the data from the kernel data structures, hence both processes can communicate.

Now, the question arises: how are these kernel data structures created? One of the two processes has to create the kernel data structures using the key information, and same key information will be used by the other process to fetch the instance of those data structures. Both the processes should have the common key information shared between them; then only both the processes can communicate.

Let us explore each of the three mechanisms one by one.

Shared Memory

The size of memory is defined by user and allocated for the processes. Both the processes will then attach themselves to this memory. Attaching to the shared memory means that their virtual addresses will be mapped to this shared memory, allowing processes to access it. If one process writes to the memory and another process can get the same information. The size of memory is shared between them.

Following are the system calls used for the shared memory implementation:

  • shmget – allocates a System V shared memory segment
  • shmat, shmdt – shared memory operations
  • shmctl – shared memory control

Example implementation of shared memory:

Writer process implementation:

#include <sys/ipc.h>   // header needed for IPC mechanism
#include <sys/shm.h> // header needed for shared memory
#include <stdio.h>   // standard header for C
int main()
{
        key_t key;
        int shmid;
        char *data

        key = ftok("tokenfile",82); // this function created the token key, which will be used by shmget

        shmid = shmget(key,1024,0666|IPC_CREAT);   // this step will create the shared memory

        data = (char*) shmat(shmid,(void*)0,0); // attach of the process address space is done here.

        printf("Write Data : ");
        gets(data);   // take the data as input from user, which can be written to the shared memory.

        printf("Data written in memory: %s\n",data);

        shmdt(data);  // once the write is done, detech the process from shared memory

        return 0;
}

Reader process:

#include <sys/ipc.h>    // header for ipc mechanisms
#include <sys/shm.h>   // header for the shared memory
#include <stdio.h>         // standard header

int main()
{
        key_t key;
        int shmid;
        char *data;

        key = ftok("tokenfile",82);

        shmid = shmget(key,1024,0666|IPC_CREAT);

        data = (char*) shmat(shmid,(void*)0,0);

        printf("Data read from memory: %s\n",data);

        shmdt(data);

        shmctl(shmid,IPC_RMID,NULL);

        return 0;
}

Example Output

The writer process has written the data as “I am john cena”. Then we executed the reader process, and it successfully read the data, and we see can the same output from the reader process.

Message Queue

These are kernel data structures implemented as message queues. Queue id is associated with each message queue. The creation and usage of this mechanism are similar to the previous one, but as the name suggests, both processes have to employ the msgsend and msgrecv functions to send and receive the data.

The following are the functions used for the message queue implementation:

  • ftok(): It can be used to generate a unique key.
  • msgget(): It returns the message queue identifier or the identifiers for a same key value queue.
  • msgsnd(): It is used to send data to other message queue.
  • msgrcv(): It is used to get the message from a queue.
  • msgctl(): It is used to do many control operations. It can be used to destroy message queue.

Example Implementation of the message Queue:

Writer process implementation:

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define MAX 1024

struct mesg_buffer {
        long mesg_type;
        char mesg_text[1024];
} message;

int main()
{
        key_t key;
        int msgid;

        key = ftok("tokenfile", 82);

        msgid = msgget(key, 0666 | IPC_CREAT);
        message.mesg_type = 1;

        printf("Write Data : ");
        fgets(message.mesg_text,MAX,stdin);

        msgsnd(msgid, &message, sizeof(message), 0);

        printf("Data send is : %s \n", message.mesg_text);

        return 0;
}

Reader process implementation:

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

struct mesg_buffer {
        long mesg_type;
        char mesg_text[1024];
} message;

int main()
{
        key_t key;
        int msgid;

        key = ftok("tokenfile", 82);

        msgid = msgget(key, 0666 | IPC_CREAT);

        msgrcv(msgid, &message, sizeof(message), 1, 0);

        printf("Data Received is : %s \n", message.mesg_text);

        msgctl(msgid, IPC_RMID, NULL);

        return 0;
}

Example Output

The writer process has sent the data as “I am john Cena” and the same data has been read by the reader process through message queue.

Here is a snapshot for the execution of the above example code.

Semaphores

Now, let us discuss an important piece of IPC, i.e., semaphore. Semaphores are not used for data sharing but for synchronizing processes accessing shared resources. For example, when the shared memory is accessed by two processes, it is essential to synchronize access to this global resource between both the processes. This is where sephamores come in as a savior.

Semaphore implementation can be done with the following kernel system calls.

  • semget() : to create and get the semaphore instance.
  • semctl() : to make the resources available and perform control operation.
  • semop() : to perform operations on the semaphore

As already mentioned, these are the synchronization mechanisms. These can be used to manage the global resources among the processes.

Conclusion

We discussed three important inter-process communication mechanism offered by the Linux kernel. Shared memory and Message queue, which we discussed with the help of example code and executed them. Sample output of the example code we discussed. Finally, we discussed the semaphore and how it can be implemented in Linux, along with the functions that can be employed to implement semaphores.

About the author

Sushil Rathore

Sushil Rathore is having hands-on experience in Linux Platform SW. He's an expert of Linux on ARM/X86 Boards. He has very good understanding on Bootloaders and other platform softwares. He has good industrial experience and have worked in reputed Organizations. Currently he is associated with a reputed firm in the networking domain.