IPC using Message Queues

Why do we need message queues when we already have the shared memory? It would be for multiple reasons, let us try to break this into multiple points for simplification −
As understood, once the message is received by a process it would be no longer available for any other process. Whereas in shared memory, the data is available for multiple processes to access.
As understood, once the message is received by a process it would be no longer available for any other process. Whereas in shared memory, the data is available for multiple processes to access.
If we want to communicate with small message formats.
If we want to communicate with small message formats.
Shared memory data need to be protected with synchronization when multiple processes communicating at the same time.
Shared memory data need to be protected with synchronization when multiple processes communicating at the same time.
Frequency of writing and reading using the shared memory is high, then it would be very complex to implement the functionality. Not worth with regard to utilization in this kind of cases.
Frequency of writing and reading using the shared memory is high, then it would be very complex to implement the functionality. Not worth with regard to utilization in this kind of cases.
What if all the processes do not need to access the shared memory but very few processes only need it, it would be better to implement with message queues.
What if all the processes do not need to access the shared memory but very few processes only need it, it would be better to implement with message queues.
If we want to communicate with different data packets, say process A is sending message type 1 to process B, message type 10 to process C, and message type 20 to process D. In this case, it is simplier to implement with message queues. To simplify the given message type as 1, 10, 20, it can be either 0 or +ve or –ve as discussed below.
If we want to communicate with different data packets, say process A is sending message type 1 to process B, message type 10 to process C, and message type 20 to process D. In this case, it is simplier to implement with message queues. To simplify the given message type as 1, 10, 20, it can be either 0 or +ve or –ve as discussed below.
Ofcourse, the order of message queue is FIFO (First In First Out). The first message inserted in the queue is the first one to be retrieved.
Ofcourse, the order of message queue is FIFO (First In First Out). The first message inserted in the queue is the first one to be retrieved.
Using Shared Memory or Message Queues depends on the need of the application and how effectively it can be utilized.
Communication using message queues can happen in the following ways −
Writing into the shared memory by one process and reading from the shared memory by another process. As we are aware, reading can be done with multiple processes as well.
Writing into the shared memory by one process and reading from the shared memory by another process. As we are aware, reading can be done with multiple processes as well.
Writing into the shared memory by one process with different data packets and reading from it by multiple processes, i.e., as per message type.
Having seen certain information on message queues, now it is time to check for the system call (System V) which supports the message queues.
To perform communication using message queues, following are the steps −
Step 1 − Create a message queue or connect to an already existing message queue (msgget())
Step 2 − Write into message queue (msgsnd())
Step 3 − Read from the message queue (msgrcv())
Step 4 − Perform control operations on the message queue (msgctl())
Here we will create two processes. One can write and another can read. Let us see how the reader and writer processes are working using shared memory.
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
// structure for message queue
struct msg_buffer {
   long msg_type;
   char msg[100];
} message;
main() {
   key_t my_key;
   int msg_id;
   my_key = ftok("progfile", 65); //create unique key
   msg_id = msgget(my_key, 0666 | IPC_CREAT); //create message queue and return id
   message.msg_type = 1;
   printf("Write Message : ");
   fgets(message.msg, 100, stdin);
   msgsnd(msg_id, &message, sizeof(message), 0); //send message
   printf("Sent message is : %s \n", message.msg);
}
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
// Define message queue structure
struct msg_buffer {
   long msg_type;
   char msg[100];
} message;
main() {
   key_t my_key;
   int msg_id;
   my_key = ftok("progfile", 65); //create unique key
   msg_id = msgget(my_key, 0666 | IPC_CREAT); //create message queue and return id
   msgrcv(msg_id, &message, sizeof(message), 1, 0); //used to receive message
   // display the message
   printf("Received Message is : %s \n", message.msg);
   msgctl(msg_id, IPC_RMID, NULL); //destroy the message queue
   return 0;
}