Linux Message Queue

Source: Internet
Author: User

Message Queue provides a simple and effective way to transmit data between two unrelated processes. Compared with the named pipe, the advantage of message queue is that it exists independently of the sending and receiving processes, which eliminates some difficulties arising from opening and closing the synchronized named pipe.

In Linux, there are two macro definitions: msgmax and msgmnb. They define the maximum length of a message and the maximum length of a queue respectively in bytes.

# Include <sys/msg. h>

Int msgctl (INT msgid, int cmd, struct msqid_ds * BUF );

Int msgget (key_t key, int msgflg );

Int msgrcv (INT msqid, void * msg_ptr, size_t msg_sz, long int msgtype, int msgflg );

Int msgsnd (INT msqid, const void * msg_ptr, size_t msg_sz, int msgflg );

1. msgget Function

We use the msgget function to create and access a message queue.

Int msgget (key_t key, int msgflg );

The first parameter can specify any key_t type variable. The second parameter msgflg consists of nine permission marks.

The msgget function returns a positive integer, that is, the queue identifier. If a message fails,-1 is returned.

2. msgsnd Function

The msgsnd function is used to add a message to a message queue.

Int msgsnd (INT msqid, const void * msg_ptr, size_t msg_sz, int msgflg );

The message structure receives two constraints: first, its length must be smaller than the upper limit set by the system. Second, it must start with a long integer member variable, the receiving function uses this member variable to determine the message type.

When using a message, it is best to define the message structure as follows:

Struct my_message

{

Long int mesage_type;

/* The data you want to send */

The first parameter msqid is the message queue identifier returned by the msgget function.

The second parameter msg_ptr is a pointer to the message to be sent. The message must start with a long integer member variable as mentioned earlier.

The third parameter msg_sz is the length of the message that msg_ptr points. This length cannot include the length of the member variable of the long integer message type.

The fourth parameter msgflg controls what will happen when the current message queue is full or the queue message reaches the system limit.

3. msgrcv Function

The msgrcv function retrieves messages from a message queue:

Int msgrcv (INT msqid, void * msg_ptr, size_t msg_sz, long int msgtype, int msgflg );

The first parameter is the message queue identifier returned by the msgget function.

The second parameter is a pointer to the message to be accepted. The message must start with a long integer member variable as described in the msgsnd function.

The third parameter msg_sz is the length of the message that msg_ptr points to. It does not include the degree of long integer Message Type member variables.

The fourth parameter, msgtype, is a long integer that implements a simple form of receiving priority. If the msgtype value is 0, the first available message in the message queue is obtained. If the value is greater than 0, the first message with the same message type is obtained. If the value is less than 0, set msgtype to-n.

The fifth parameter msgflg is used to control what will happen when there is no corresponding type of message in the message queue to receive.

4. msgctl Function

The last message queue function is msgctl, which is very familiar with the control functions of shared memory.

Int msgctl (INT msgid, int cmd, struct msqid_ds * BUF );

The msqid_ds structure contains at least the following members:

Struct msqid_ds

{

Uid_t msg_perm.uid;

Uid_t msg_perm.gid;

Mode_t msg_perm.mode;

}

The first parameter msqid is the identifier of the Message Queue returned by the msgget function.

The second parameter command is the action to be taken. It can take three values.

Command
Description

Ipc_stat
Set the data in the msqid_ds structure to the current 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 msqid_ds structure.

Ipc_rmid
Delete a message queue.

The function returns 0 in total and-1 in case of failure.

/* Here's the receiver program. */#include <stdlib.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <sys/msg.h>struct my_msg_st {    long int my_msg_type;    char some_text[BUFSIZ];};int main(){    int running = 1;    int msgid;    struct my_msg_st some_data;    long int msg_to_receive = 0;/* First, we set up the message queue. */    msgid = msgget((key_t)1234, 0666 | IPC_CREAT);    if (msgid == -1) {        fprintf(stderr, "msgget failed with error: %d\n", errno);        exit(EXIT_FAILURE);    }/* Then the messages are retrieved from the queue, until an end message is encountered. Lastly, the message queue is deleted. */    while(running) {        if (msgrcv(msgid, (void *)&some_data, BUFSIZ,                   msg_to_receive, 0) == -1) {            fprintf(stderr, "msgrcv failed with error: %d\n", errno);            exit(EXIT_FAILURE);        }        printf("You wrote: %s", some_data.some_text);        if (strncmp(some_data.some_text, "end", 3) == 0) {            running = 0;        }    }    if (msgctl(msgid, IPC_RMID, 0) == -1) {        fprintf(stderr, "msgctl(IPC_RMID) failed\n");        exit(EXIT_FAILURE);    }    exit(EXIT_SUCCESS);}

/* The sender program is very similar to msg1.c. In the main set up, delete the msg_to_receive declaration and replace it with buffer[BUFSIZ], remove the message queue delete and make the following changes to the running loop. We now have a call to msgsnd to send the entered text to the queue. */#include <stdlib.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <sys/msg.h>#define MAX_TEXT 512struct my_msg_st {    long int my_msg_type;    char some_text[MAX_TEXT];};int main(){    int running = 1;    struct my_msg_st some_data;    int msgid;    char buffer[BUFSIZ];    msgid = msgget((key_t)1234, 0666 | IPC_CREAT);    if (msgid == -1) {        fprintf(stderr, "msgget failed with error: %d\n", errno);        exit(EXIT_FAILURE);    }    while(running) {        printf("Enter some text: ");        fgets(buffer, BUFSIZ, stdin);        some_data.my_msg_type = 1;        strcpy(some_data.some_text, buffer);        if (msgsnd(msgid, (void *)&some_data, MAX_TEXT, 0) == -1) {            fprintf(stderr, "msgsnd failed\n");            exit(EXIT_FAILURE);        }        if (strncmp(buffer, "end", 3) == 0) {            running = 0;        }    }    exit(EXIT_SUCCESS);}

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.