Here's how to use Message Queuing for interprocess communication, and Message Queuing has a lot in common with named pipes. For more information about named pipes, see my other article: Linux interprocess Communication--Using Named pipes
First, what is Message Queuing
Message Queuing provides a way to send a block of data from one process to another. Each block of data is considered to contain a type, and the receiving process can independently receive data structures that contain different types. We can avoid the synchronization and blocking of named pipes by sending messages. However, Message Queuing, like named Pipes, has a maximum length limit for each block of data.
Linux uses macros Msgmax and MSGMNB to limit the maximum length of a message and the maximum length of a queue.
Second, using Message Queuing in Linux
Linux provides a series of function interfaces for Message Queuing to allow us to easily use it to implement interprocess communication. Its usage is similar to the other two system V pic mechanisms, that is, semaphores and shared memory.
1. Msgget function
This function is used to create and access a message queue. Its prototype is:
int Msgget (key_t, key, int msgflg);
As with other IPC mechanisms, a program must provide a key to name a particular message queue. MSGFLG is a permission flag that represents the access rights of a message queue, as it does with file access. MSGFLG can be done or manipulated with ipc_creat to create a message queue when the message queue named by key does not exist, and if the message queue named by key exists, the IPC_CREAT flag is ignored and only one identifier is returned.
It returns the identifier of a message queue named key (Non-zero integer), which returns 1 when it fails.
2. msgsnd function
This function is used to add messages to the message queue. Its prototype is:
int msgsend (int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);
MsgId is the message queue identifier that is returned by the Msgget function.
Msg_ptr is a pointer to prepare to send a message, but the data structure of the message has a certain requirement, the message structure pointed to by the pointer msg_ptr must be a struct with a long integer member variable, the receiving function will use this member to determine the type of message. So the message structure is defined as this:
struct my_message{
long int message_type;
/* The data you wish to transfer*/
};
MSG_SZ is the length of the message that msg_ptr points to, note the length of the message, not the length of the entire structure, that is, MSG_SZ does not include the length of the long integer message type member variable.
MSGFLG is used to control what will happen when the current message queue is full or when the queue message reaches the system-wide limit.
If the call succeeds, a copy of the message data is placed in the message queue and returns 0, which returns-1 when it fails.
3. Msgrcv function
This function is used to get messages from a message queue, and its prototype is
int MSGRCV (int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);
MsgId, Msg_ptr, Msg_st function as well as functions msgsnd functions.
Msgtype can implement a simple receive priority. If Msgtype is 0, the first message in the queue is fetched. If its value is greater than 0, the first information with the same message type is obtained. If it is less than 0, gets the first message that the type is equal to or less than the absolute value of the msgtype.
MSGFLG is used to control what happens when no corresponding type of message in the queue can be received.
When the call succeeds, the function returns the number of bytes placed in the receiving buffer, the message is replicated to the user-allocated buffer in the msg_ptr point, and the corresponding message in the message queue is deleted. Returns-1 when failed.
4. Msgctl function
This function is used to control Message Queuing, which is similar to the SHMCTL function of shared memory, and its prototype is:
int msgctl (int msgid, int command, struct msgid_ds *buf);
command is the action to take, it can take 3 values,
Ipc_stat: Sets the data in the MSGID_DS structure to the current association value of the message queue, which overwrites the Msgid_ds value with the current association value of the message queue.
Ipc_set: If the process has sufficient permissions, set the current association value of the message queue to the value given in the MSGID_DS structure
IPC_RMID: Deleting message queues
BUF is a pointer to the MSGID_DS structure, which points to the Message Queuing mode and the structure of the access permission. The MSGID_DS structure includes at least the following members:
struct Msgid_ds
{
uid_t shm_perm.uid;
uid_t Shm_perm.gid;
mode_t shm_perm.mode;
};
Returns 0 on success and 1 on failure.