Linux interprocess communication-Message Queuing Msgget (), Msgsend (), MSGRCV (), Msgctl ()

Source: Internet
Author: User

Here's how to use Message Queuing for interprocess communication, where Message Queuing has a lot in common with named pipes. More about Named pipes can be found in 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 problems of named pipes by sending messages. But Message Queuing, like named Pipes, has a maximum length limit for each block of data.

Linux uses macro Msgmax and MSGMNB to limit the maximum length of a message and the maximum length of a queue.

ii. using Message Queuing in Linux

Linux provides a series of function interfaces for Message Queuing that allow us to easily use it for interprocess communication. Its usage is similar to the other two system V pic mechanisms, i.e. 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);

Like 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 for Message Queuing, which is the same as file access. MSGFLG can be done or manipulated with ipc_creat, which means that when a message queue named by key is not present, a message queue is created, and if a message queue named by key is present, the IPC_CREAT flag is ignored and only one identifier is returned.

It returns an identifier for a message queue named key (nonzero integer), which returns 1 on failure.

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 returned by the Msgget function.

Msg_ptr is a pointer to prepare to send a message, but the data structure of the message has certain requirements, the pointer msg_ptr the message structure must be a long integer member variable start structure, the receive function will use this member to determine the type of message. So the message structure should be defined like this:

struct My_message {    long int message_type;    /* The data wish to transfer */};

MSG_SZ is the length of the message that the MSG_PTR points to, note the length of the message, not the length of the entire struct, that is, the length of the member variable that MSG_SZ does not include the long integer message type.

The MSGFLG is used to control what will happen when the current message queue is full or the queue message reaches the system-wide limit.

If the call succeeds, a single copy of the message data is placed in the message queue and returns 0, returning 1 on failure.

3. MSGRCV () function

This function is used to get the message 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 functions as function msgsnd () function.

The Msgtype can implement a simple receive priority. If Msgtype is 0, it gets the first message in the queue. If its value is greater than 0, it gets the first information with the same message type. If it is less than 0, it gets the first message with a type equal to or less than the absolute value of Msgtype.

The MSGFLG is used to control what happens when there are no corresponding types of messages in the queue that can be received.

When the call succeeds, the function returns the number of bytes placed in the receive buffer, the message is copied to the user-allocated buffer that is pointed to by msg_ptr, and the corresponding message in the message queue is deleted. Returns-1 on failure.

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 that will be taken, it can take 3 values,

    • Ipc_stat: Sets the data in the MSGID_DS structure to the current associated value of the message queue, which overwrites the value of Msgid_ds with the current association value of the message queue.
    • Ipc_set: If the process has sufficient permissions, set the current association value for the message queue to the value given in the MSGID_DS structure
    • IPC_RMID: Deleting Message Queuing

BUF is a pointer to the MSGID_DS structure that points to the structure of the Message Queuing pattern and access rights. 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, 1 on failure.

iii. using Message Queuing for interprocess communication

Nonstop, after describing the definition of Message queuing and the interfaces that can be used, let's look at how it makes the process communicate. Since it is possible to allow unrelated processes to communicate with each other, we will write two programs here, Msgreceive () and msgsned () to represent receiving and sending information. According to normal circumstances, we allow two programs to create a message, but only if the recipient finishes receiving the last message, it deletes it.

The source code for the program source file that receives the information is msgreceive.c:

#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include < errno.h> #include <sys/msg.h>struct msg_st{long int msg_type;char text[bufsiz];}; int main () {int running = 1;int MsgId = -1;struct msg_st data;long int msgtype = 0;//note 1//Establish message queue MsgId = Msgget ((key_t) 12 34, 0666 | Ipc_creat); if (MsgId = =-1) {fprintf (stderr, "Msgget failed with Error:%d\n", errno); exit (exit_failure);} Gets the message from the queue until the end message is encountered while (running) {if (MSGRCV (MsgId, (void *) &data, Bufsiz, msgtype, 0) = =-1) {fprintf (stderr, "M SGRCV failed with errno:%d\n ", errno); exit (exit_failure);} printf ("you wrote:%s\n", data.text),//Encounters end End If (strncmp (Data.text, "End", 3) = = 0) {running = 0;}} Delete Message Queuing if (Msgctl (MsgId, ipc_rmid, 0) = =-1) {fprintf (stderr, "Msgctl (ipc_rmid) failed\n"); exit (exit_failure);} Exit (exit_success);}

The source code for the program that sent the message MSGSEND.C is:

#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys /msg.h> #include <errno.h> #define MAX_TEXT 512struct msg_st{long int msg_type;char text[max_text];}; int main () {int running = 1;struct Msg_st data;char buffer[bufsiz];int msgid = -1;//Establish message Queue MsgId = Msgget ((key_t) 1234, 066 6 | Ipc_creat); if (MsgId = =-1) {fprintf (stderr, "Msgget failed with Error:%d\n", errno); exit (exit_failure);} Writes a message to the message queue until it writes Endwhile (running) {//Input data printf ("Enter some text:"); fgets (buffer, Bufsiz, stdin);d Ata.msg_type = 1;< c0/>//Note 2strcpy (data.text, buffer);//Send data to queue if (Msgsnd (MsgId, (void *) &data, max_text, 0) = =-1) {fprintf (stderr, "M Sgsnd failed\n "); exit (exit_failure);} Input end End Input if (strncmp (buffer, "End", 3) = = 0) {running = 0;} Sleep (1);} Exit (exit_success);}

The results of the operation are as follows:

Iv. Example Analysis--Message type

Here is the main explanation of what the message type is, note the variable msgtype (note 1) defined in the main () function of the msgreceive.c file, which acts as the value of the receive information type parameter of the MSGRCV () function, with a value of 0, which indicates getting the first available message in the queue. Look again at the statement in the while loop in the msgsend.c file Data.msg_type = 1 (note 2), which is used to set the type of information that is sent, that is, the type of information it sends is 1. So the program msgreceive () can receive the information sent by the program Msgsend ().

If you take note 1, that is, the statement in the main () function of the msgreceive.c file is represented by a long int msgtype = 0; change to a long int msgtype = 2; What happens, msgreceive () will not be able to receive the program Msgsend () Send the information. Because when the MSGRCV () function is called, if Msgtype (the fourth argument) is greater than 0, only the first message with the same message type is obtained, the modified message type is 2, and msgsend () sends a message type of 1, so it cannot be msgreceive () The program receives. Recompile the msgreceive.c file and execute it again, with the following results:

As we can see, msgreceive does not receive the information and output, and when msgsend input end, msgreceive is not finished, and through the jobs command we can see that it is still running in the background.

v. Comparison of message queues and named Pipes

Message Queuing is much the same as named Pipes, where the process of communicating Message Queuing, like a named pipe, can be unrelated processes, and they all pass data in a way that is sent and received. In a named pipe, send data with write (), receive data with read (), then in message queue, send data with msgsnd (), receive data with MSGRCV (). And they have a maximum length limit for each data.

The advantage of Message Queuing compared to named Pipes is that:

1. Message Queuing can also exist independently of the send and receive processes, eliminating the difficulties that can arise when synchronizing the opening and closing of named pipes.

2. By sending messages, you can also avoid the synchronization and blocking problems of named pipes, and do not need to provide synchronization methods by the process itself.

3. The receiving program can selectively receive data through the message type, instead of being received only by default, as in a named pipe.

Reference:

http://blog.csdn.net/ljianhui/article/details/10287879

"Linux High Performance Server Programming"

"UNIX Network Programming _ volume 2_ interprocess communication"

Linux interprocess communication-Message Queuing Msgget (), Msgsend (), MSGRCV (), Msgctl ()

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.